Reputation: 493
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
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
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