0

Please note that I'm a beginner with Angular 2 and asynchronous loading. The following questions helped me on the right track, but don't seem to answer this exact question:

I have a jQuery script that should run in an Angular 2 project, but cannot seem to find the right way to get these scripts to load in the right sequence. The script finds a certain DOM element and turns it into a custom radial slider (using http://roundsliderui.com).

This is the sequence I want:

  1. JSON call to get data
  2. ***.component.html gets filled with <li *ngFor="let item of items" ...</li>
  3. roundSlider script loads and transformli elements to roundSliders (radial slider controls)

What seems to be happening is that the Angular2 Component that handles the JSON call always loads (or finishes) after the jQuery script that displays the controls for the loaded data. This means that the jQuery script successfully loads, but has no DOM elements to reference.

For some reason it just doesn't help to use Lifecycle hooks like ngAfterViewInit, which sounds like it should be sufficient. The only lifecycle hook that does work is ngAfterViewChecked, but this causes trouble with using the actual control that is generated (because it then also fires the script when you use the slider).

I thought it would be smart to try and use the ngOnInit hook to call the scripts in sequence, but that also doesn't work.

How can a simple jQuery script be tought to wait for a JSON call to finish getting data and the DOM elements (ngFor) to load?

Community
  • 1
  • 1
dbj
  • 115
  • 1
  • 7

1 Answers1

2

Without you showing some of your code, I guess it's the usual question about how to use Observables.

Indeed ngAfterViewInit seems like the right place to start, but there's more to it, since you're talking about making a JSON call. When the JSON gets returned from http.get/post, you're in a callback. That callback fires whenever the async operation finishes, hence everything after that http call might get executed before the call finishes.

I'd suggest putting your JQuery calls into that subscribe callback along the lines of this example:

this.http.get("url")
    .map(res => res.json())
    .subscribe(data => {
        this.data = data;
        $("selector")....
    });

EDIT:

On second thought, the view might not have rendered your data yet at this point. So maybe you still could use ngAfterViewChecked and check, if your data variable is filled and maybe have a boolean variable holding the initialized state so it only executes once after your data has been loaded.

ngAfterViewInit() {
    if (this.data != null && !this.initialized) {
        this.initialized = true;
        $("selector")...
    }
}
Maximilian Riegler
  • 22,720
  • 4
  • 62
  • 71
  • 1
    you're right about not knowing enough about Observables, but you definitely helped me on the right track here. This way the actual script fires AFTER the data is loaded and the HTML is built, but only fires once. – dbj Sep 12 '16 at 09:55