What is the proper way to return from within an angular subscription?

旧时模样 提交于 2021-01-29 10:58:28

问题


Disclaimer: This is a "good programming practices" question rather than a "fix my broken code" question.

Environment

Angular 5.2.9, Angular Material 5.2.4, Typescript 2.4.2, Rxjs 5.5.8

Issue

I am using the mat-dialog component of the angular material library, and subscribing to the observable returned from afterClosed(). Inside of that subscription I have a simple if statement. If value is returned, return value, otherwise return null. My tslint is throwing a fit about returning from inside the async subscription. The exact error is, "TS2355: A function whose declared type is neither 'void' nor 'any' must return a value."

Code

private openModal() : string {

    // some setup code

    this.dialog.open(MyModalComponent, configModal)
        .afterClosed()
        .subscribe(( data : string ) => {
            if ( data ) {
                return data;
            } else {
                return null;
            }
        });

    // cant put return here,  this will execute before modal returns data

}

Question

I want to specify a return type 'string' to my function, but that means I need to do the actual return from within the synchronous function openModal(), and not the async code inside the subscription. I am open to all suggestions on how to improve this code. Thanks!


回答1:


Actually, your code is kind of broken and this is not only about good programming practices.

You are using an Observable, that makes your code asynchronous. Once your code is asynchronous, it will never become synchronous again and you have to use asynchronous types until the very last consumer of your function. In an Angular application this is usually a Component or Directive.

This is a core concept of JavaScript and is most prominently applied with Observables, Promises and Callback Functions. It is vital to understand how asynchronous code execution and the JavaScript event loop works in order to work with this programming language.

As for your code example, you need to change the return type of your function to Observable<string> and pass the observable on to your component class where you can assign it to a property and let Angular handle the rest.

It looks like this:

private openModal() : Observable<string> {

    // some setup code

    return this.dialog.open(MyModalComponent, configModal)
        .afterClosed();
}

Then in your component...

private data: string;

clickSomeButton()  {
    this.openModal().subscribe(data => this.data = data);
}


来源:https://stackoverflow.com/questions/52506013/what-is-the-proper-way-to-return-from-within-an-angular-subscription

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!