how to call a function after the termination of another function in angular

how to call a function after the termination of another function in angular



I have 3 functions and I would like to call one after the other


openTryFunction()
// function one
this.functionOne();
// after function one
this.functionTwo();
// after function two
this.functionTree();





And what issue are you having in doing that? It should be fine...
– user184994
Aug 31 at 12:53





one depends on the outcome of the other
– Nikolas Soares
Aug 31 at 12:56





Yep, still don't see an issue here unless the functions are asynchronous.
– user184994
Aug 31 at 12:57





@user184994 functionOne() and functionTwo() may be asynchronous.
– Rohit Sharma
Aug 31 at 12:57


functionOne()


functionTwo()





in typescript is asynchronous, so the next function depends on the previous
– Nikolas Soares
Aug 31 at 12:59




6 Answers
6



So you have three functions functionOne, functionTwo, and functionThree. There can be multiple PnCs of whether any of these functions is synchronous or asynchronous.


functionOne


functionTwo


functionThree



Let's generalize these scenarios into two main categories:



All are synchronous: If this is the case, your code is going to run one after the other(synchronously).



If any of the function is async: If this is the case, then the function that is async in nature should let the function that is supposed to be called after that, to know that it has terminated. In this case, you can either return a Promise/Observable from that async function. Or you can pass it a callback function that will get called after the async function finishes execution.



Two examples of this would be:



Then you should be writing it like:


openTryFunction()
this.functionOne()
.subscribe(
() => this.functionTwo()
.subscribe(() => this.functionThree()
.subscribe(() => console.log('Function three terminated')))
);


functionOne


functionTwo




openTryFunction()
this.functionOne().then(() =>
this.functionTwo().then(() => this.functionThree());
);



Update:



You can also use async and await for a cleaner code. Here's a simple yet concrete example for the same:


async


await




import Component from '@angular/core';
import HttpClient from '@angular/common/http';

@Component(
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
)
export class AppComponent
name = 'Angular';
users;

constructor(private http: HttpClient)

ngOnInit()
this.getAllData();


getUsers()
return this.http.get('https://jsonplaceholder.typicode.com/users')
.toPromise();


getUserPosts(userId)
return this.http.get(`https://jsonplaceholder.typicode.com/posts?userId=$userId`)
.toPromise();


getPostComments(postId)
return this.http.get(`https://jsonplaceholder.typicode.com/comments?postId=$postId`)
.toPromise();


async getAllData()
const users = await this.getUsers();
const posts = await this.getUserPosts(users[0].id);
const comments = await this.getPostComments(posts[0].id);

console.log(users);
console.log(posts);
console.log(comments);




Here's a StackBlitz for the same.



Hope that makes sense.





Small suggestion: with this code you won't know when functionTree has completed
– user184994
Aug 31 at 13:23


functionTree



You can use Promise:


functionOne(): Promise<any>
return Promise.resolve((() =>
// code here
return 'from first'; // return whatever you want not neccessory
)());


functionTwo(): Promise<any>
return Promise.resolve((() =>
// code here
return 'from second'; // return whatever you want not neccessory
)());


functionThree()
// code here




this.functionOne().then(data1 =>
console.log(data1);
this.functionTwo().then(data2 =>
console.log(data2);
this.functionThree();
);
);





A promise must be resolved instead of returning.
– Faisal
Aug 31 at 13:22





@Faisal Hmm, It is resolving an anonymous function that is returning something.
– Rohit Sharma
Aug 31 at 13:25






You can resolve the data e.g. resolve('from second');
– Faisal
Aug 31 at 13:28


resolve('from second');





Yes, the function is to do extra work.
– Rohit Sharma
Aug 31 at 13:38




If your functions are synchronous what you are doing is fine. If they are asynchronous and they return promises then you can string them together as so:


fOne()
.then(() =>
fTwo()
).then(() =>
fThree()
);



Alternatively you can use an async await.


async function tasks()
await fOne();
await fTwo();
await fThree();



Be sure to us try catch to handle exceptions.



If your functions return observables then concatMap is your friend.


fOne()
.concatMap(() => fTwo())
.concatMap(() => fThree());



Given your last function Does not return a promise you can omit await on the last call assuming you use async await.



If the functions return an observable, then simply call the next function in subscribe. Otherwise, return a promise from each function. Then you can chain the called functions.


subscribe


functionOne()
return new Promise((resolve) =>
//
// Your function implementation
//
// Resolve the promise at the end
resolve();
);


functionTwo()
return new Promise((resolve) =>
//
// Your function implementation
//
// Resolve the promise at the end
resolve();
);


functionThree()
return new Promise((resolve) =>
//
// Your function implementation
//
// Resolve the promise at the end
resolve();
);



openTryFunction()
// function one
this.functionOne().then(() =>
// after function one
this.functionTwo().then(() =>
// after function two
this.functionTree();
);
);



Look at this example where each function returns an Observable and the sequence of execution is controlled by a concat function.


Observable


concat


export class AppComponent implements OnInit
name = 'Angular';
values = ;

first(): Observable<string>
return of('first');


second(): Observable<string>
return of('second');


afterSecond(): Observable<string>
return of('secondish');


third(): Observable<string>
return of('third');


ngOnInit()
let sequence = concat([
this.first,
this.second,
this.afterSecond,
this.third]);

sequence.subscribe(currentFunction =>
currentFunction().subscribe(value =>
this.values.push(value);
)
);





I like the concat function as it build an Observable of the functions we add to the list.


concat


Observable



Note that this call sequence.subscribe(currentFunction each value in currentFunction will be a function, and in order to have the actual value of it, as it is an Observable you need to subscribe to it.


sequence.subscribe(currentFunction


currentFunction


Observable



Please see the full example here: https://stackblitz.com/edit/angular-functions-in-sequence?file=src%2Fapp%2Fapp.component.ts



you can try this,


openTryFunction()
this.functionOne().then(()=>this.functionTwo().then(() => this.functionTree()))



function 3 will run when 2 is done and 2 will run when 1 is done.





Only if the first and the second function returns promise.
– Rohit Sharma
Aug 31 at 13:03



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Some of your past answers have not been well-received, and you're in danger of being blocked from answering.



Please pay close attention to the following guidance:



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)