Working with multiple instances of ace editor

Hi,
Thank you so much for such a great product.
I have implemented convergence in my angular with the ace editor and it is working superb for a single screen.
I’m having issues with the multiple ace editor screens at a time.

E.g. There are total 5 buttons. When I click on the 1st button I’m able to see the editor and its contents in the ace editor. But when I click on the second button I want to change the editor code and want to show the code associated with the convergenceExampleId. But when i try to jump it is throwing errors like you have opened model already,etc.

How do I use convergence for multiple ace editor instances.

Thanks in advance

Hello, without a screenshot or any code examples it’s hard to supply much guidance, but first of all I’d make sure that each Ace editor is bound to its own RealTimeModel, and that you’re closing models appropriately when an editor is closed.

Are these editors in the same browser, or across multiple browsers?

@alec @michael Thanks for your reply.

In the above image suppose we are on 1st question. In this, for the first question, it is showing “Hi, This is the first question” as editor contents. When I click on the next question button, the convergence should change the editor’s contents. It should replace text from “Hi, This is the first question” to “Hi, This is the second question” as shown in the below image.

I want to change the editor contents based on button click.
Here only 1 ace editor is used just I wanted to change the contents.

I understand now. I assume you were using the Ace Collaborative Extensions. I am guessing that the editor is bound to a particular model and that perhaps it is not getting unbound correctly when trying to switch the editor.

Do you have any code you could share, or the error you are seeing?

hi @michael
Thanks for your reply.

Below is the angular code.

Initial function call

    Convergence.connectAnonymously(this._url, "suhas")
      .then(d => {
        this.domain = d;

        // Now open the model, creating it using the initial data if it does not exist.
        return this.domain.models().openAutoCreate({
          collection: "employee",
          id: "first",
          //ephemeral: true,
          data: { text: "This is first question" }
        });

      }).then(res => {                
        this.currentModel = res;
        this.handleOpen(res);
      }).catch(error => {
        console.error("Could not open model ", error);
      });

When I click on the next question button, the below code gets executed -

next() {
    this.domain.models().openAutoCreate({
      collection: "employee",
      id: "second",
      data: { text: "This is second question contents"}
    }).then(res => {
      this.handleOpen(res);
    });
  }

When I click on the previous question button, the below code gets executed -

prev() {
    this.domain.models().openAutoCreate({
      collection: "employee",
      id: "first",
      data: { text: "This is first question contents"}
    }).then(res => {
      this.handleOpen(res);
    });
  }

Please let me know if you require any additional information.

Rather than binding a separate model to each question, could you instead re-use the same model? So your data could look like e.g.

{ 
  questions: [
    "This is first question contents",
    "This is the seconds question contents"
  ]
}

Then, you don’t have to go through the overhead of opening / closing so many models, and you could just bind the contents of an array index to the ace editor.

Otherwise, it’d be helpful to see what is in the handleOpen(res) function.

Hi @alec
Thank you for your reply.
I have tried your suggestion but it is returning error,

Below is the code.

Convergence.connectAnonymously(this._url, this.username)
      .then(d => {
        this.domain = d;

        this.domain.models().openAutoCreate({
          collection: "employee",
          id: "first",          
          data: {
            text:
              [
                { "first": "This is first question contents" },
                { "second": "This is the second question contents" }
              ]
          }
        }).then(res => {          
          this.handleOpen(res);
        });
      }).catch(error => {
        console.log("Could not open model ", error);
      });

handleOpen function -

    handleOpen(model) {      
        this.editor = ace.edit("ace-editor");
        this.editor.setTheme('ace/theme/monokai');

        this.session = this.editor.getSession();
        this.session.setMode('ace/mode/javascript');
        this.doc = this.session.getDocument();

        const textModel = model.elementAt("text");
        this.initModel(textModel);    
      }

I’m facing an error inside initModel()

initModel(textModel) {

    const session = this.editor.getSession();    
    session.setValue(textModel.value()[0].first);

    textModel.on("insert", (e) => {      
      const pos = this.doc.indexToPosition(e.index);
      this.suppressEvents = true;
      this.doc.insert(pos, e.value);
      this.suppressEvents = false;
    });

    textModel.on("remove", (e) => {

      const start = this.doc.indexToPosition(e.index);
      const end = this.doc.indexToPosition(e.index + e.value.length);
      this.suppressEvents = true;
      this.doc.remove(new this.AceRange(start.row, start.column, end.row, end.column));
      this.suppressEvents = false;
    });

    textModel.on("value", function (e) {
      this.suppressEvents = true;
      this.doc.setValue(e.value);
      this.suppressEvents = false;
    });

    this.editor.on('change', (delta) => {

      if (this.suppressEvents) {
        return;
      }

      const pos = this.doc.positionToIndex(delta.start);

      switch (delta.action) {
        case "insert":         
          textModel.insert(pos, delta.lines.join("\n"));  **<= Error occured here**
          break;
        case "remove":
          textModel.remove(pos, delta.lines.join("\n").length);
          break;
        default:
          throw new Error("unknown action: " + delta.action);
      }
    });
  }

I’m facing an error in the switch, inside the insert event.
Below is the screenshot of an error which occurs when I type something in the editor

Thank you.