Search code examples
javascriptangulartypescriptstring-interpolationjavascript-import

Imports and exports in angular


I am working on an angular project having a few components. There is a const object that is being exported in a .ts file and it is being imported in two components.

export const topology = {
  "topologyName": '',
  "hosts": [],
  "switches": [],
  "hostLinks": [],
  "switchLinks": []
}

It so appears that changing the imported object's properties values in one component changes the imported same object's properties in another components. I verified the code and am sufficiently sure that I am not some how passing the data between the components.

  1. My question is that do the two imports, of the same exported object above in a .ts file, in the two components refer to the same object in the memory or are independent?

  2. And as a separate question; in one of the components I have used string interpolation in a div element in which I have called a method which has to display a .json data in the embedded editor(ace).

    <div class="code-editor" #codeEditor>
       {{ displayCode() }}
    </div>
    

This is the method. (The 'topology' object was the object that was imported into this component and some other, as I said previoulsy)

 @ViewChild('codeEditor', {static:true}) codeEditorElmRef: ElementRef;
 private codeEditor: ace.Ace.Editor;

 displayCode() {
   // console.log('Called again');
   const element = this.codeEditorElmRef.nativeElement;
   const editorOptions: Partial<ace.Ace.EditorOptions> = {
     readOnly: true,
     autoScrollEditorIntoView: true,
     showPrintMargin: false,
     highlightActiveLine: false,
     highlightGutterLine: false,
     cursorStyle: "slim",
     minLines: 37,
     maxLines: 37,
   };

   topology.hosts.sort();
   topology.switches.sort();
   topology.hostLinks.sort();
   topology.switchLinks.sort();

   this.codeEditor = ace.edit(element, editorOptions);
   this.codeEditor.setTheme(THEME);
   this.codeEditor.getSession().setMode(LANG);
   this.codeEditor.setShowFoldWidgets(true);
   this.codeEditor.setAutoScrollEditorIntoView( true );
   this.codeEditor.getSession().setValue(JSON.stringify(topology, null, '\t'));
 }

When I uncomment the console.log statement, it is logging 'Called again' in the console infinitely and the browser hangs. Is this how angular behaves? Should we not call a method in string interpolation as it would be called continuously? Or am I wrong somewhere?

Could you please clarify the doubts? So thankful to you.


Solution

  • As I wrote above: Yes, if you export an object from one file and import it in multiple other files, all imports will refer to the same object instance.

    Regards displayCode(): You call displayCode() in each change detection cycle of the component by calling it directly from the template. At the same time, you are most likely modifying parts of the component that trigger change detection again:

    this.codeEditor = ace.edit(element, editorOptions);
    

    This will lead into an endless loop.

    Generally, I recommend to not perform any data changes in methods called directly from the template. Additionally, it often makes sense not to call any methods from the template at all to avoid issues like that, but instead store display values to properties of the component from lifecycle hooks (onInit, ...) and render them, avoiding cycles like this one.