Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript and Angular, order of execution in this

I have the following code inside an Angular application, the html looks like so.

<ng-multiselect-dropdown
    (onSelect)="onSubstringSelect($event)">
</ng-multiselect-dropdown>

That onSubstringSelect is in the .ts part of the component:

onSubstringSelect(item: any) {
    const dataPois = this.getPois(data);
    alert("2nd alert " + dataPois);
    // etc
}

getPois(data): any[] {
    this.api.getPois(data).subscribe((result: any) => {
        alert("1st alert");
        return result.pois;
        }
    }, (error: any) => {
        console.error('error', error);
        return {};
    });

    return null;
}

I was expecing that I had first the alert("1st alert"); and then alert("2nd alert " + dataPois); but that alert is executing first. Why?

like image 488
pmiranda Avatar asked Jun 03 '19 21:06

pmiranda


People also ask

Is TypeScript and Angular are same?

Angular is a modern framework built entirely in TypeScript, and as a result, using TypeScript with Angular provides a seamless experience. The Angular documentation not only supports TypeScript as a first-class citizen, but uses it as its primary language.

Does Angular use JS or TS?

TypeScript is a primary language for Angular application development. It is a superset of JavaScript with design-time support for type safety and tooling.

What is ngOnInit in Angular?

ngOnInit()link A callback method that is invoked immediately after the default change detector has checked the directive's data-bound properties for the first time, and before any of the view or content children have been checked. It is invoked only once when the directive is instantiated.


2 Answers

This is because Rx Streams are asynchronous. When you set up your stream, it does indeed set it up; but nothing runs until there's something listening to this. In the Rx world, this is called subscribing.

When you hand off your stream to the AsyncPipe using stream$ | async; it'll subscribe and all the functions within the setup stream will start functioning in order.

This seems counter intuitive at first, but it actually makes a lot of sense. If you want your console.log to run in the order you want them, add tap() operators in order or redefine your stream to match your expectation.

When you do this:

function A() {
    const stream$ = this.http.get('my-stream-url').pipe(
            tap(() => { console.log('stream is live!') })
        )
    console.log('But this will show up first, because nothing is listening to the stream$ yet!')
    return stream$
}

You can see how the stream will stay stagnant, until someone starts listening to it by subscribing.

like image 118
Bjorn 'Bjeaurn' S Avatar answered Oct 03 '22 01:10

Bjorn 'Bjeaurn' S


You do not know when the asynchronous data will be returned. In this case, the answer comes after doing alert("2nd alert " + dataPois);.

like image 37
Kamil Augustyniak Avatar answered Oct 03 '22 03:10

Kamil Augustyniak