How to send data from one routed component to another

I am trying to send data from one routed component to another using RxJS Subject by the click of a button. The value is showing in console inside subscription but is not reflecting in the template/view.

Also, is using a subject the right way of sharing data between routed components, if not then what should I use?

StackBlitz link:

home.html

<input #input placeholder="Enter something">
<button (click)="onSubmit(input.value)">Submit</button>

home.ts

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { SubjectService } from '../subject.service';
@Component({ selector: 'app-home', templateUrl: './home.component.html', styleUrls: ['./home.component.css']
})
export class HomeComponent { constructor(private router: Router, private ser: SubjectService) { } onSubmit(value: string) { console.log(value); this.ser.send(value); this.router.navigate(['result']); }
}

result.ts

import { Component, OnInit } from '@angular/core';
import { SubjectService } from '../subject.service';
@Component({ selector: 'app-result', templateUrl: './result.component.html', styleUrls: ['./result.component.css']
})
export class ResultComponent implements OnInit { constructor(private ser: SubjectService) { } data = 'Data before it has changed'; ngOnInit(): void { console.log('result'); this.ser.source$.subscribe((message) => { this.data = message; console.log('Inside subcription:' + this.data); }); }
}

result.html

<p>Result page: </p>
<p>Data : {{data}}</p>

SubjectService.ts:

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';
@Injectable({ providedIn: 'root'
})
export class SubjectService { constructor() { } private source = new Subject<any>(); source$ = this.source.asObservable(); send(message : string){ this.source.next(message); }
}

App.component.html

<ul> <li><a routerLinkActive="active" routerLink="/home">Home</a></li> <li><a routerLinkActive="active" routerLink="/result">Result</a></li>
</ul>
<p>Router Outlet: </p>
<router-outlet></router-outlet>

App-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { ResultComponent } from './result/result.component';
const routes: Routes = [ { path: 'result', component: ResultComponent }, { path: 'home', component: HomeComponent }, { path: '', redirectTo:'home', pathMatch:'full'}
];
@NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule]
})
export class AppRoutingModule { }

The data variable is not updating in the result page.

3

1 Answer

The problem is that you're firing the source$ observable before the results view is even initialized. If you start on your home view and enter a value you will not see the Here it is updating log in the console.

You don't really need a subject for your example, a simple service that holds your shared data in a property is plenty enough:

import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root', }) export class SubjectService { public value: string | null = null; }

You can update this property by assigning it a value, e.g.

onSubmit(value: string) { this.ser.value = value; this.router.navigate(['result']); }

and in your results page you can define a getter to the service variable, which will always return the current value:

 public get data() { return this.ser.value || 'Value is empty'; }

Stackblitz demo

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like