Han Che
Han Che

Reputation: 8519

angular 2, return Observables according to if statement

Hi I want create something like this.

someFunction():Observable<Response>{
  let response$ = new Observerable();

  if (...){
    response$ = this.http.get(url1)
  }else{
    response$ = this.http.get(url2)
  }
  return response$
}

if I subscribe to it, i'm getting an error

Cannot read property 'subscribe' of undefined

Thanks for all the help in advance!

EDIT--------- this is the actual function using ionic 2 and cordova. It checks whether the app is on a mobile device or not and opens a popup with url (intend to be used for social logins)

Once the window closed I will need to perfom a http.get request to fetch a token from my backend.

public social(providerName:string):Observable<Response>{

let response$ = new Observable<Response>();
let url =providerName+'/someUrl'

let authWindow;

if(window.cordova){
    let authWindow= InAppBrowser.open(url, '_blank', 'location=no');

    authWindow.addEventListener('loadstop', event => {
        if(event.url.indexOf(`${providerName}/callback`) > -1){
            authWindow.close()
        }
    });

    authWindow.addEventListener('loaderror', event =>{
        if(event.url.indexOf(`${providerName}/callback`) > -1){
            authWindow.close()
        }
    });

    authWindow.addEventListener('exit', () => {
        setTimeout(()=>{
             response$ = this.http.get(...)
        },500)
    })

}else{
    authWindow = createWindow(popupUrl);
    let window = Observable.interval(1000);

    let  pingWindow = window.subscribe(
        ()=>{
            if(authWindow.closed){
                pingWindow.unsubscribe();

                response$ = this.http.get(...)

            }
        })
}

return response$

}

Upvotes: 1

Views: 2059

Answers (1)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 658225

The update reveals the problem.
You are not assigning to response$ directly but in async callbacks. When return response$ is executed, none of the assignments to response$

    setTimeout(()=>{
         response$ = this.http.get(...)
    },500)

nor

let  pingWindow = window.subscribe(
    ()=>{
        if(authWindow.closed){
            pingWindow.unsubscribe();

            response$ = this.http.get(...)

        }
    })

were executed yet.

The 1st is executed 0.5s later, the 2nd when the function passed to window.subscribe(...) is executed because of an emitted value which will be at some point later.

public social(providerName:string):Observable<Response>{

    let response$ = new Subject<Response>();
    let url =providerName+'/someUrl'

    let authWindow;

    if(window.cordova){
        let authWindow= InAppBrowser.open(url, '_blank', 'location=no');

        authWindow.addEventListener('loadstop', event => {
            if(event.url.indexOf(`${providerName}/callback`) > -1){
                authWindow.close()
            }
        });

        authWindow.addEventListener('loaderror', event =>{
            if(event.url.indexOf(`${providerName}/callback`) > -1){
                authWindow.close()
            }
        });

        authWindow.addEventListener('exit', () => {
            setTimeout(()=>{
                 this.http.get(...)
                 .map(val => val.json())
                 .subscribe(val => response$.next(val);
            },500)
        })

    }else{
        authWindow = createWindow(popupUrl);
        let window = Observable.interval(1000);

        let  pingWindow = window.subscribe(
            ()=>{
                if(authWindow.closed){
                    pingWindow.unsubscribe();

                    this.http.get(...)
                    .map(val => val.json())
                    .subscribe(val => response$.next(val);
                }
            })
    }

    return response$.asObservable()
}

This should fix at least your immediate problem.

Upvotes: 1

Related Questions