Nuthan Kumar
Nuthan Kumar

Reputation: 493

Observable fork join does not work

H, I am having issues in properly using rxJs observable. My requirement is to get all chat rooms on a Book (if room is not available create one new chat room) I am using below code and the observable in chat component never getting called.

my Chat component

@Component({
selector: 'chat',
templateUrl: './chat.component.html'
})
export class ChatComponent implements OnInit {
this.selectbookStream.subscribe(bookId=>
{ 
 this.chatService.getRooms(book id)
    .subscribe(rooms => {
      console.log("in chat component");
      console.log(rooms);
      this.rooms = rooms;
    });
})
}

My chat Service

@Injectable()
 export class ChatService {
    public getRooms(bookID) {
      console.log("in get rooms")
      return this.thisPartyChatService.createRooms(bookID).map(r=>r)

   }
 }

ThirdParty chat service

 public createRooms(bookID: string): Observable<any> {
let rooms = [];

this.modelService.getBookDetails(bookID).subscribe(book=> {

  this.getRoom(book.name).subscribe(r => {
    if (Object.keys(r).length === 0) {
     rooms.push( this.createRoom(book.name).map(res=>res))
    } else {
     // rooms.push(Observ)
      rooms.push(Observable.of({
        'id': r.id,
        'type': r.type,
        'title': r.title,
        'name': r.title,
        'created': r.created
      })
      )
    }

  })

});
return Observable.forkjoin(rooms);

}


 public createRoom(bookID: string): Observable<any> {
    return this.http.post(this.apiUrl.room, { 'title': bookID, 'teamId': 
        teamId }, this.generateHeader()).map(res => res.json);
  }

  public getRoom(modelId: string): Observable<any> {
    this.roomTitle = modelId;
    // search all rooms in CISCO sparck and match with modelId
     return this.http.get(this.apiUrl.room, this.generateHeader())
         .map(this.findRoom);
  }


  private findRoom(res: Response) {
   let body = res.json();
  let room: any;
  body.items.forEach(element => {
  if (element.title == this.roomTitle)
    return element;
  });
  return {};
 }

Upvotes: 0

Views: 488

Answers (2)

martin
martin

Reputation: 96891

I think the problem is in the structure of createRooms() method. Basically you have the following:

public createRooms(bookID: string): Observable<any> {
    let rooms = [];

    this.modelService.getBookDetails(bookID).subscribe(book => {
        this.getRoom(book.name).subscribe(...);
    })

    return Observable.forkjoin(rooms);
}

Nesting subscribe() calls is always a warning sign.

I guess getBookDetails or getRoom are asynchronous functions so when the code reaches return Observable.forkjoin(rooms) the rooms array is always empty.

So I'd recommend you to restructure your code. For example like this (I didn't test it but you should get the point).

public createRooms(bookID: string): Observable<any> {
    return this.modelService.getBookDetails(bookID)
        .concatAll()
        .concatMap(book => this.getRoom(book.name))
        .concatMap(room => {
            if (Object.keys(r).length === 0) {
                return Observable...
            } else ....

        });
}

Upvotes: 1

Federico Pettinella
Federico Pettinella

Reputation: 1511

It may be that the service isn't being called since you need to call it inside of a function. For example, your component implements OnInit so you could put your service call inside that function and have the component end up like this:

@Component({
    selector: 'chat',
    templateUrl: './chat.component.html'
})
export class ChatComponent implements OnInit {

    public rooms = [];

    public ngOnInit() {

        this.selectbookStream.subscribe(bookId => { 
             this.chatService.getRooms(book id)
                .subscribe(rooms => {
                  console.log("in chat component");
                  console.log(rooms);
                  this.rooms = rooms;
                });
        })  
    }
}

Upvotes: 0

Related Questions