Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing value between two components (pages) in Angular 2

I am using Angular 2 (TypeScript)

I have two components (actually they are two pages too). They are NOT parent and child relationship.

I want to pass a value to second component(page) when I click the link in the first component(page).

I know "URL parameters" way through router. But I don't want to show this parameter in the link. Is there any other way?

Thank you!

like image 471
Hongbo Miao Avatar asked Jan 23 '16 04:01

Hongbo Miao


Video Answer


2 Answers

Thank you MarkM! It works, but it has been difficult for me because I have it all in diferent files and over last angular2 using angular cli... So I explain it here:

First of all: You need to create a file with the class you want to share with other components: data.service.ts and make it "@Injectable":

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

@Injectable()
export class myService {
  public sharedData:string;

  constructor(){
    this.sharedData = "String from myService";
  }

  setData (data) {
    this.sharedData = data;
  }
  getData () {
    return this.sharedData;
  }
}

Make sure you set the created class (myService) on 'providers' only once on the app.module.ts file and import the injectable file: data.service.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { routing, appRoutingProviders } from './app.routing';
import { AppComponent } from './app.component';
import { AppContent } from './components/content.component';
import { AppInsertContent } from './components/insert.component';
import { myService } from './services/data.service';

@NgModule({
  declarations: [
    AppComponent,
    AppContent,
    AppInsertContent,
  ],
  imports: [
    BrowserModule,
    routing
  ],
  providers: [appRoutingProviders, myService],
  bootstrap: [AppComponent]
})
export class AppModule { }

Wherever you want to use your shared class use the constructor to create an object from the class (this object will be unique for your components, thanks to the @Injectable decorator). Remember to import it on every file you use it!...

In my case this view sets the data of the object with a text input: input.component.ts

import { Component } from '@angular/core';
import { myService } from '../services/data.service';

@Component({
  selector: 'insert-content',
  template: `
   <input id="textbox" #textbox type="text">
   <button (click)="this._myService.setData(textbox.value); SharedData = textbox.value;">SAVE</button>
   Object data: {{SharedData}}

    <div class="full-button">
      <a routerLink="/" routerLinkActive="active">BACK</a>
    </div>
  `
})

export class AppInsertContent {
  SharedData: string;
  constructor (private _myService: myService){
    console.log(this._myService.getData());
  }
}

And in this view I just see the data that has been set on the object: content.component.ts

import { Component } from '@angular/core';
import { myService } from '../services/data.service';

@Component({
  selector: 'app-content',
  template: `
  <div style="float:left; clear:both;"> 
    {{_myService.getData()}} 
  </div>

  <div class="full-button">
    <a routerLink="/insert" routerLinkActive="active">INSERT</a>
  </div>
  `
})
export class AppContent {
  constructor (private _myService: myService){
    console.log(this._myService.getData());
  }
}

I hope this info is usefull!

like image 70
gtamborero Avatar answered Oct 09 '22 02:10

gtamborero


The canonical way is to establish an injectable service and inject the service into any components that need the data. Since the service is a singleton, the components will be accessing the same data. It shouldn't matter that they are on different pages. Plunker here.

Edit: Here's a more involved example that shows two-way communication between components by subscribing to an eventEmitter on a service: Plunker

import {Component, Injectable} from 'angular2/core'

// your shared service 
// provide reference in parent component or bootstrap 
@Injectable()
export class myService {
  sharedData:string = "String from myService"
}

@Component({
  selector: 'page1',
  providers: [],
  template: `
    <div>
      <b>Component Page1 - shared data:</b> {{SharedData}}
    </div>
  `,
  directives: [],
})
export class Page1 {
  constructor(aService: myService) {
    this.SharedData = aService.sharedData
  }
}

@Component({
  selector: 'page2',
  providers: [],
  template: `
    <div>
      <b>Component Page2 - shared data:</b> {{SharedData}}
    </div>
  `,
  directives: [],
})
export class Page2 {
  constructor(aService: myService) {
    this.SharedData = aService.sharedData
  }
}
like image 44
Mark Avatar answered Oct 09 '22 02:10

Mark