Always_a_learner
Always_a_learner

Reputation: 5055

sending dynamic data from one route to other

I want to send data from students/my-students route to students/student-profile/:id both belong to different module which is child module of student-post-login module.

In my-students.html

<div *ngFor="student of students">
<a (click)="goToStudentProfile(student)"> student name </a>
</div>

my-students.ts

goToStudentProfile(student) {

  let studentData = { "firstName": student.firstname,
    "phone": student.phone,
    "email": student.email,
    "birthdate": student.birth_date
    }

  this.studentsService.studentBasicInfo = []
  this.studentsService.studentBasicInfo.push(studentData );
this.router.navigate(['students/student-profile/student.student_id'])

}

In studentsService I have studentBasicInfo public field declared as

studentBasicInfo = [];

student-profile component:

ngOnInit()
{
 console.log("studentBasicInfo", this.studentsService.studentBasicInfo) 
}

//Output: studentBasicInfo  undefined

I tried this with behaviorSubject as well but may be both components are from different module so that is also not working.

Any ideas that how I can fix this?

UPDATE I have also tried:

my-students.component.ts

this.studentsService.setData(studentsData)

service:

studentData = new BehaviorSubject<any>(null)
studentData$ = this.studentData.asObservable();
setData(data)
{
    this.studentData.next(data)
}

student-profile.component.ts

ngOnInit(){

this.studentService.studentData$.subscribe(

data=>
{
  console.log("subscribed",data)
})
}

//Output subscribed

Explained my scenario: stackblits But unfortunately it is not working due to dependency issue.

UPDATE: This part of answer from Aniket avhad solved my problem:

In order two share a service between multiple components, you should provide the service at a level higher and not add the service to the providers of both components.

Upvotes: 1

Views: 119

Answers (4)

Aniket Avhad
Aniket Avhad

Reputation: 4145

Ok here is your solution, your rxjs BehaviorSubject will also worked, only you have to do that is add service where you initialize rxjs studentData and add that service into main module provider.

In order two share a service between multiple components, you should provide the service at a level higher and not add the service to the providers of both components.

Now check my solution here,

first create common.service.ts

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

@Injectable({
  providedIn: 'root'
})
export class CommonService {

  studentData = new BehaviorSubject<any>(null)
  studentData$ = this.studentData.asObservable();

  constructor() { }

}

and in app.component.ts

export class AppComponent {
  name = 'Angular';

  constructor(private router: Router, private commonService: CommonService) { }

  ngOnInit() {
  }

  students = [
    { id: 1, name: 'student1' },
    { id: 2, name: 'student4' },
    { id: 3, name: 'student3' },
    { id: 4, name: 'student2' }

  ];

  goToStudentProfile(student) {
    let studentData = {
      "firstName": student.name,
      "id": student.id,
    }

    this.commonService.studentData.next(studentData);
    this.router.navigate([`student/${student.id}`]);
  }
}

and in child.component i.e. your student

ngOnInit() {
    this.commonService.studentData$.subscribe(res => {
      console.log(res);
    });
  }

Stackblitz demo

Upvotes: 1

masera ngelekanyo
masera ngelekanyo

Reputation: 53

can you please try this.

<div *ngFor="student of students">
<button mat-raised-button color="primary" class="btn btn-secondary" routerLink="/students/student-profile/{{student.id}}"> Update User</button>
</div>

and then use ActivatedRoute to get your id on your destination module.

import { ActivatedRoute} from '@angular/router'; 

    constructor( route: ActivatedRoute) {
        var userId = route.snapshot.params['id'];
       }

Upvotes: 0

Suresh Kumar Ariya
Suresh Kumar Ariya

Reputation: 9774

You can also trying using RXJS BehaviorSubject.

Service:

export class studentsService {
  private transferData = new BehaviorSubject<any>('');
  public transferData$ = this.transferData.asObservable();

  setData(data) {
    this.data = data;
    this.transferData.next(this.data);
  }
}

**In your Component**

 ngOnInit() {
    setTimeout(()=>{
    this._studentsService.transferData$.subscribe(
      (data) => {
        console.log(data);
      }
    );
    }, 500);
  }

Upvotes: 0

The problem is that you output data only when component is initializing. Try to use RxJS to subscribe on data changing.

export class studentsService {
  dataUpdated:EventEmitter = new EventEmitter();

  setData(data) {
    this.data = data;
    this.dataUpdated.emit(this.data);
  }
}

And your component:

ngOnInit() {
    this._studentsService.dataUpdated.subscribe(
      (data) => {
        console.log(data);
      }
    );
  }

Upvotes: 0

Related Questions