2

I'm new to programming and angular2.. Here I'm trying to send object from one component to other on click event using service but i'm not getting any data..

this is parent component...

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',
    providers:[SelectedItemService],
    template:`<p>

    </p>
    <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="my_base_url/{{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="my_base_url";
        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;

      }
}

this is child component...

import {Component,Input} from '@angular/core';
import {SelectedItemService} from './selecteditem.service'
@Component({
    selector:'secondcomponent',
    providers:[SelectedItemService],
    template:`<h1> This is second new Component</h1>
    {{UiSelectedItem}}


   `

})
export class SecondComponent{
     UiSelectedItem:JSON;
     constructor(public mservice:SelectedItemService) {
        this.mservice=mservice;
        this.UiSelectedItem=mservice.selectedItem;

     }

}

this is service.ts..

import { Injectable } from '@angular/core';

    @Injectable()
    export class SelectedItemService {
        selectedItem:JSON;
    }

Also I'm not sure if I'm doing it right please suggest...

Sangwin Gawande
  • 7,658
  • 8
  • 48
  • 66
coder007
  • 97
  • 7

1 Answers1

1

Don't add SelectedItemService to providers of the component. This way every component will get it's own instance. Add it to providers of NgModule instead, then you'll have a single instance for the whole application.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Thank u so much for your time.... this is working occasionally... most of the times im getting it as undefined data... only twice out of 10 times i was able to view the result on the screen... rest of the times is still showing blank... Any idea why this could be happening... – coder007 Oct 05 '16 at 18:13
  • Probably a timing issue. When you read `mservice.selectedItem` it might not yet have arrived from the server. You need to chain async calls using observables otherwise you can't expect reliable behavior. For nice examples see https://angular.io/docs/ts/latest/cookbook/component-communication.html. – Günter Zöchbauer Oct 05 '16 at 18:18
  • when u say server u mean the lite server??? coz the mservice.selectedItem is not depending on any api calls for data... im trying to pass the already fetched data to a different component.. So will it happe in such cases as well?? – coder007 Oct 05 '16 at 18:50
  • So your `http.get()` call is unrelated to the problem? If you set the data of the service in `onSelect()` and copy it in the constructor of `SecondComponent` the service won't have the data yet. If you copy the data in the constructor and later the are changed in `onSelect()` there is no connection with the created copy. You need to copy the value again to get the updated value in `SecondComponent`. This is what `Observables` are for. They notify subsrcibers about changes. – Günter Zöchbauer Oct 05 '16 at 20:14
  • but why will the data change in onselect... The scenario is like this... in parent component im making http call which ll retun me list of images on the screen... and on clicking the image the data(object) of that particular image that's already available should be sent to child component... so in onselect im initialising the service object variable with clicked image's object.. Should i Use observable in such scenario.. Can you please provide workaround.. I just went through lot of articles but couldn't get how to implement it.. Thanks in advance – coder007 Oct 06 '16 at 10:07
  • If it's a direct child, then you can just bind to an `@Input()` of that child ``. If not, then I'd use an observable so that the receiving component gets notified about the new value. – Günter Zöchbauer Oct 06 '16 at 10:10
  • @Input() wont work coz it is not a direct child... that's why i'm depending on service now... so i i shd now implement observable to make service work as expected right?? – coder007 Oct 06 '16 at 10:16
  • Yes, use an observable in the service. In the child use `service.someObservable.subscribe(...)` or if you want to bind to it `{{service.someObservable | async}}`. The link I posted in my first comment has several examples. – Günter Zöchbauer Oct 06 '16 at 10:18
  • i tried to implement as u suggested.. can u pls look into this issue.. http://stackoverflow.com/questions/39895805/angular-2-trying-to-implement-observables-in-services – coder007 Oct 06 '16 at 12:19
  • 1
    Sorry for troubling you... got the issue finally actually i created hyperlink within image tag and onclick was directly going to new page and onclick method was not getting called in the parent component and hence there was no objet data sent :-D – coder007 Oct 07 '16 at 11:24
  • So you figured it out? Glad to hear. Thanks for the update. – Günter Zöchbauer Oct 07 '16 at 11:25