Angular2 - Use value of Observable returning method in another Observable
Asked Answered
B

2

7

The problem

I dont know how to use the value of the currently returned Observable of getUserHeaders() in my http.get.

Current error

Type 'Observable<void>' is not assignable to type 'Observable<Participant[]>'

Expected result

Being able to use the value of my Observable returning method getUserHeaders() as a headers attribute within the http call. While only returning the http call's Observable.

Previous code

(which worked with harcoded Headers returned by getUserHeaders() (so not an Observable or Promise).

getAllParticipants(): Observable<Array<Participant>> {
    return this.http.get('someUrl',
                {headers: this.getUserHeaders()})
           .map(response => {
               return response.json();
        });
    });
   }

Current code

going by Chaining RxJS Observables from http data in Angular2 with TypeScript 's answer I came to the flatMap method. (note this code currently throws the 'current error')

getUserHeaders(): Observable<Headers> {
        let headers: Headers = new Headers();

        return NativeStorage.getItem("user").map(
            data => {
                headers.append('API_KEY', data.json().apiKey);
                headers.append('DEVICE_ID', data.json().deviceId);
                return headers
            }).catch( error => {
                console.log("error");
                headers.append('API_KEY', 'TEST');
                headers.append('DEVICE_ID', 'TEST');
                return headers;
            }
        );
    }

/** retrieves ALL the participants from the database */
    getAllParticipants(): Observable<Array<Participant>> {

         return this.getUserHeaders().flatMap( data => {
            return this.http.get('someUrl', {headers: data}).map(response => {
                return response.json();
            });
        });
   }

plunkr (Promise instead of Observable)

http://plnkr.co/edit/A0tEB9EUodWQS6AnqrtH?p=info

(note: Observable.fromPromise() didn't work here so I have created the two methods returning promises -- now I want to use the value of getUserHeaders() inside the promise of getParticipants() and still return the promise/observable of getParticipants() and nothing from getUserHeaders()

Berky answered 15/11, 2016 at 15:2 Comment(10)
What exactly is the proble here, is it typing problem? Any way, Array<Participant> is wrong here because response.json() is any.Invective
response.json() is confirmed to be an Array<Participant> note: the method getAllParticipants worked well before, I'm just trying to incorporate the Headers from the getUserHeaders() methodBerky
It isn't Array<Participant> from Typescript's perspective. And you didn't explain what is the problem.Invective
@estus edited the question, I think I made it a bit more clear, if still unclear, please comment :)Berky
It isn't clear what error message is and why it happens. The solution itself looks ok, MCVE is what the question lacks.Invective
@estus errormessage VSCode gives me is this: Type 'Subscription' is not assignable to type 'Observable<Participant[]>'. Property '_isScalar' is missing in type 'Subscription'. (property) APICaller.http: HttpBerky
This message suggests that .subscribe is done in this method. It isn't possible to resolve your issue without MCVE. The code you've posted looks ok to me but it can differ from real appInvective
@estus, excuse me I had the wrong method in my code, this is the correct error Type 'Observable<void>' is not assignable to type 'Observable<Participant[]>'Berky
@estus, added plunkr, with promises instead of Observables, see question for detailsBerky
Please, be specific when you're talking about errors. Runtime errors and compiler errors are totally different things. 'Observable<void>' is not assignable to type 'Observable<Participant[]>' is type error. Returned type should be Observable<any>, just because response.json() is untyped. It's not clear what Observable.fromPromise() didn't work here means, and I don't see what's wrong with plunker you've posted. It is not possible to solve a problem if it isn't clear what exactly the problem is.Invective
O
4

Change your getUserHeaders() to look like:

getUserHeaders(): Observable<any> { return Observable.of(NativeStorage.getItem("user"); }

Then construct your headers object within getParticipants(). This way you can keep flatMap

Ortiz answered 16/11, 2016 at 13:31 Comment(1)
where in getParticipants should i construct my headers?Berky
S
0

Personally, the solution to my problem was to use BehaviorSubject:

In service (source of the data):

private theBoolean: BehaviorSubject<boolean>;

constructor() {
    this.theBoolean = new BehaviorSubject<boolean>(false);
}

public getTheBoolean(): Observable<boolean> {
    return this.theBoolean.asObservable();
}

To emit new value of theBoolean do smth like

public setTheBoolean(newValue: boolean): void {
    this.theBoolean.next(newValue);
}

In component (user of the data):

this.theService.getTheBoolean().subscribe(value => console.log(value));

Credit to "pashozator" on Reddit

Shortwave answered 12/6, 2018 at 13:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.