12322

Angular 2 trying to implement Observables in services

Question:

Im trying to send data from one component to other using observable. Here I'm implementing observable in service like this...

import { Injectable } from '@angular/core'; import { Observable } from 'rxjs/RX' @Injectable() export class SelectedItemService { stream1$:Observable<any>; selectedItem:JSON; stream1$= new Observable(observer=> setTimeout(() => { observer.next(this.selectedItem); }, 3000);) }

and my parent Component is initializing data to a service in onselect() like below :

import { Component } from '@angular/core'; import {Http, Headers,Response } from '@angular/http'; import {Observable} from 'rxjs/Rx'; import 'rxjs/add/operator/map'; import {SelectedItemService} from './selecteditem.service' @Component({ selector: 'newcomponent', template:`

<h2>Your Title: {{nameValue}}</h2> <ul><li *ngFor="let list of lists">Hello {{ list }}</li></ul> <form class="ui large form segment"> <h3>Add a Link</h3> <div> <label for="title">Title:</label> <input [(ngModel)]="nameValue" placeholder="title" name="Title" > </div> <label for="link">Link:</label> <input name="link"></form> <div class=container *ngFor="let data of dataServer" [class.selected]="data === selectedItem" (click)="onSelect(data)"> <div id="myimages"> <a routerLink="/SecondNewCom"> <img src="myBaseurl/{{data.images.image3}}"> </a> <router-outlet></router-outlet> </div> <div class=caption> {{data.productName}} </div> </div>`, styleUrls: [`./app/mydoc.css`] }) export class NewComponent { nameValue: string; lists: string[]; url:string; dataServer:JSON[]; length:number; selectedItem:JSON; constructor(private http:Http, public myservice:SelectedItemService) { this.myservice=myservice; this.nameValue = "declaredName"; this.url="myBaseurl"; this.lists = ['abc', 'xyz', 'lol']; this.http.get(this.url).map((res:Response) => res.json()) .subscribe( data => { this.dataServer = data this.length=Object.keys(this.dataServer).length}, err => console.error(err), () => console.log('done') );} onSelect(data:JSON):void{ this.selectedItem=data; this.myservice.selectedItem=data; } }

and child component is receiving the data from subscriber like this... but the data displayed is undefined and i see blank screen.. Where am i doing wrong...

import {Component,Input} from '@angular/core'; import {SelectedItemService} from './selecteditem.service' @Component({ selector:'secondcomponent', template:`

This is second new Component

{{UiSelectedItem}}

` }) export class SecondComponent{ UiSelectedItem:JSON; constructor(public mservice:SelectedItemService) { this.mservice=mservice; mservice.stream1$.subscribe(value=>this.UiSelectedItem=value); } }

Answer1:

What you should be using is a Subject. If you have ever used Angular's EventEmitter, this is also a Subject. With EventEmitter we usually use it to publish events from child to parent

@Component({ template: ` <child (textChange)="onTextChange()"></child> ` }) class ParentComponent {} class ChildComponent { @Output() textChange = new EventEmitter(); onClick() { textChange.emit('new value'); } }

It's you've ever used this before, this is is the publish/subscribe pattern that you need. Someone subscribes to the event, and someone publishes it. This is where we can use Subject. As I said EventEmitter is a subclass of Subject.

For this case though, the vanilla Subject may not be good enough. The reason is that once the event is emitted, it is gone forever. If there was no one subscribed, nothing happens with it. So if it happens that you subscribe just a smidget after the event was emitted, then you get nothing. A lot of times this is unacceptable.

For this case, we can use a ReplaySubject. This type of subject allows you to keep a buffer with configurable size. So if you subscribe right after the event was emitted you will still get it.

Here's an example

import { ReplaySubject } from 'rxjs/ReplaySubject'; export class SelectedItemService { private _selectedItem = new ReplaySubject<string>(1); // buffer size 1 selectedItem$ = this._selectedItem.asObservable(); set selectedItem(item: string) { this._selectedItem.next(item); } }

Now the component that wants to publish just needs to set the item

service.selectedItem = 'new item';

And the subscribing component

service.selectedItem$.subscribe(item => {})

<strong>See Also:</strong>

<ul><li><a href="https://stackoverflow.com/q/39885264/2587435" rel="nofollow">What are RxJS Subject's and the benifits of using them?</a></li> <li><a href="http://reactivex.io/rxjs/manual/overview.html#subject" rel="nofollow">RxJS docs on Subjects</a></li> </ul><hr /><h2>UPDATE</h2>

See <a href="http://plnkr.co/edit/MDj0eE7q18F4tAtXzXrk?p=preview" rel="nofollow"><strong>Plunker</strong></a>

Answer2:

You should use Observable.create instead of new Observable

See : <a href="http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-create" rel="nofollow">RxJs docs</a>

Recommend

  • Inject a Class with GIN
  • OpenCV with Laplacian formula to detect image is blur or not in Android
  • Add class to parent element
  • Ioniv-v4 : ionic cordova plugin add cordova-plugin-googleplus Not working
  • What happens when one of the Kafka replicas is down
  • c++ plugin : Is it ok to pass polymorphic objects?
  • Cron and nightmarejs
  • get value using jquery
  • Haskell function that outputs all combinations within the input list that add to the input number
  • AJAX calls - where does logic go?
  • Reveal Icon Button - Bootstrap 3
  • magento 2 rest api : get cart items with images
  • Pass multiple lines of stdin input to interactive Java command line program, non-interactively
  • QueryOver - add restriction on primitive collection
  • Spotify Apps API: get other users' playlists
  • Joining across databases with dbplyr
  • Turn Inline OnClick to Click Jquery
  • E: Malformed entry 1 in list file /etc/apt/sources.list.d/sbt.list (Suite)
  • connect.cookieParser and connect.session
  • Questions related to Garbage Collector and finalize() method
  • Videos won't upload
  • Slick: How can I combine a SQL LIKE statement with a SQL IN statement
  • How to get a time and Date Separately?
  • In metro, get all inherited classes of an (abstract) class?
  • Auto send email based on the time and email address in database
  • Validating my form with Jquery
  • Defer unused CSS
  • Modifying native query cannot have named parameter bindings?
  • Query takes almost two seconds but matches only two rows - why isn't the index helping?
  • How to use Flask's render_template from an ajax POST form submit
  • ASP.NET MVC 2 actions for the same route?
  • concise way of flattening multiindex columns
  • Google Spreadsheet Script to Blink a range of Cells
  • How to clear a browser cache in Protractor
  • How to integrate angular2-material (alpha 8.2) with angular2-Quickstart app
  • Send array to next viewcontroller iOs xcode [duplicate]
  • Comma decimal separator is ignored by ASP.NET MVC model binder
  • Apple Mach-O Linker error (“duplicate symbol”)
  • WPF custom control and direct content support
  • Running R's aov() mixed effects model from Python using rpy2