quid
quid

Reputation: 67

How to wait until subscribe finishes | Angular 9

My task is to create a method in contest.service.ts that will get data (contests) from server, do the necessary manipulations with it and return the result.

contest.service.ts:

    getContests() {
        let id = IDs.contests.getAll;
        let body = { 
            ...
        };

        let result;

        this.wsservice.send(id, body);

        this.wsservice.on<any>(IDs.contests.getAll)
            .subscribe((msg) => {
                console.log('msg', msg);
                if (!msg['code']) {
                    result = msg;
                    console.log('contests msg', result);
                    this.contests = result.map(contest => {
                        return new Contest({
                            id: contest.id,
                            name: contest.name || "Нет названия",
                            description: contest.description,
                            contestTasks: contest.tasks || []
                        });
                    });
                }
                else {
                    result = "Error";
                }
            });

        return result;
    }

I need to wait until subscription to this.wsservice.on(IDs.contests.getAll) finishes and then return the result from it. Methods from websocket.service.ts:

    public send(eventId: any, data: any = {}): void {
        console.log('SEND');
        let that = this;
        if (eventId && this.isConnected && this.websocket$) {
            data['id'] = eventId;
            this.websocket$.next(data);
        } else {
            setTimeout(function() {
                that.send(eventId, data);
            }, 500);
            console.log('Still connecting, resending messsage...');
        }
    }

    public on<T>(eventId: any): Observable<T> {
        console.log(eventId);
        if (eventId) {
            return this.wsMessages$.pipe(
                filter((message: IWsMessage<T>) => message.id === eventId),
                map((message: IWsMessage<T>) => message.result ? message.result : message.error)
            );
        }
    }

Upvotes: 0

Views: 1869

Answers (1)

Eliseo
Eliseo

Reputation: 57909

Improving my comment.

You should return an observable. You can use

getContests() {
   ....
   return this.wsservice.on<any>(IDs.contests.getAll).pipe(
    //we don't want the response else
    switchMap(msg)=>{
      ..do something with the msg..
      //create an object
      const contest= new Contest({
                 ...});
       //we need return an observable, we use rxjs operator 'of'
       return of(contest)
   }
   )

Or use map

getContests() {
   ....
   return this.wsservice.on<any>(IDs.contests.getAll).pipe(
    //we are going to transform the response
    map(msg)=>{
      ..do something with the msg..
      //create an object
      const contest= new Contest({
                 ...});
       return contest; //<--see that return simple the object
   }
   )

See that return an observable, so in you component subscribe

this.service.getContests().subscribe(res=>{
   //here you has the object contest
   console.log(res)
})

Upvotes: 1

Related Questions