alia
alia

Reputation: 459

async function not working when called in ngOnInit

In angular, I'm using service to get the current location of the page an change the title of the page accordingly and for that, I'm using an async function which is working in normal case when a button is pressed but when the page loads and in ngOnInit it does not work in order.

async getPageName(): Promise < any > {

    await this.router.events.subscribe(event => {

        if (event instanceof NavigationEnd) {
            console.log("url ", event.url);
            var index = this.pageNameHeader.findIndex(function(page) {
                return page.location == event.url.replace("/", "");
            })
            this.pageName = this.pageNameHeader[index].name
        }
    });
    console.log(this.pageName, " initialize");

    return this.pageName;
}

controller

  this.commonService.getPageName().then(data=>{
  this.pageName = data
})

in the normal case the second log is coming in order but in ngOnInit it comes first.I'm not using observable here to return data because before the event.subscribe completes ,the getPageName function returns an empty string i.e old data.

Upvotes: 0

Views: 934

Answers (3)

mchl18
mchl18

Reputation: 2336

Rewrite to use a proper promise should help

getPageName(): Promise <any> {
    return new Promise((resolve, reject) => {
        this.router.events.subscribe(event => {
            if (event instanceof NavigationEnd) {
                console.log("url ", event.url);
                var index = this.pageNameHeader.findIndex(function(page) {
                    return page.location == location.pathname.replace("/", "");
                });
                if (index) {
                    resolve(this.pageNameHeader[index].name);
                } else { 
                    reject();
                }
            }
        });
    });
}

Then you can do

async ngOnInit() {
  this.pageName = await this.getPageName();
}

Upvotes: 2

Leo
Leo

Reputation: 751

The await keyword works only on Promise object, but this.router.events.subscribe() expression returns a Subscription object.

You should try using the toPromise() method of observables:

async getPageName(): Promise < any > {
    await this.router.events.toPromise().then(event => {
        if (event instanceof NavigationEnd) {
            console.log("url ", event.url);
            var index = this.pageNameHeader.findIndex(function(page) {
                return page.location == location.pathname.replace("/", "");
            });
            this.pageName = this.pageNameHeader[index].name
        }
    });
    console.log(this.pageName, " initialize");
    return this.pageName;
}

Upvotes: 0

Christian Vincenzo Traina
Christian Vincenzo Traina

Reputation: 10444

You are awaiting a Subscription object, which is neither a Promise nor a Promise-like.

You can convert your Observable into a Promise using the toPromise method:

const event = await this.router.events.toPromise();
if (event instanceof NavigationEnd) {
// etc

Upvotes: 0

Related Questions