Change the param name & ID with the next previous buttons

74 Views Asked by At

How I can change the params id and name with the previous and next buttons? The Id is changing but the name is not changing in the route and component. Also, I wanted to add the limit with ID. I only have the 5 students in the array where I'm getting the student's name and id.

ngOnInit() {

  // Display Student ID in the Component
  this.route.params.subscribe(data => {
    this.stdID = data['id'];
    this.stdNAME = data['name'];
    console.log(this.stdID);
  })

}

previousStudent(){
  let previousID = parseInt(this.stdID) - 1;
  let previousNAME = this.stdNAME;
  this.router.navigate(['/students', previousID, previousNAME])
}

nextStudent(){
  let nextID = parseInt(this.stdID) + 1;
  let nextNAME = this.stdNAME;
  this.router.navigate(['/students', nextID, nextNAME])
}

app.routing.ts

const routes: Routes = [
  { path:'', component: HomeComponent },
  { path:'home', component: HomeComponent, pathMatch: 'full' },
  { path:'student-data', component: StudentDataComponent },
  { path:'students', component: StudentListComponent}, 
  { path:'students/:id/:name', component: StudentDetailsListComponent},
  { path:'**', component: NotFoundComponent },
];

studentListComponent.html

<p>Student detail works</p>

<h3>This is Student ID : {{stdID}}</h3>
<h3>This is Student NAME : {{stdNAME}}</h3>

<br>
&nbsp;
<button type="button" class="btn btn-outline-success" (click)="previousStudent()">Previous Student</button>
&nbsp;
&nbsp;
<button type="button" class="btn btn-outline-success" (click)="nextStudent()">Next Student</button>
2

There are 2 best solutions below

1
Yong Shun On
  1. You need a singleton service to store the student array in the (root) application. In the service, you should implement methods to get previous or next student by current student's id.
@Injectable({
  providedIn: 'root',
})
export class StudentService {
  public students: any[] = [];

  constructor() {
    this.getStudents().subscribe({
      next: (students) => {
        this.students = students;
      },
    });
  }

  getStudents() {
    return of([/* Students */]); // Observable of students array
  }

  getPreviousStudent(id: number) {
    let currentIndex = this.students.findIndex((x) => x.id == id);
    let index = currentIndex - 1;

    return of(this.students[index]);
  }

  getNextStudent(id: number) {
    let currentIndex = this.students.findIndex((x) => x.id == id);
    let index = currentIndex + 1;

    return of(this.students[index]);
  }
}
  1. In your StudentDetailListComponent, you should get the injected StudentService and store the previous and next student by current student's id.
previousStud!: any | null;
nextStud!: any | null;

constructor(
  private router: Router,
  private route: ActivatedRoute,
  private studentService: StudentService
) {}

ngOnInit() {
  // Display Student ID in the Component
  this.route.params.subscribe((data) => {
    this.stdID = data['id'];
    this.stdNAME = data['name'];
    console.log(this.stdID);

    this.studentService.getPreviousStudent(parseInt(this.stdID)).subscribe({
      next: (student) => {
        this.previousStud = student;
      },
    });

    this.studentService.getNextStudent(parseInt(this.stdID)).subscribe({
      next: (student) => {
        this.nextStud = student;
      },
    });
  });
}

previousStudent() {
  this.router.navigate([
    '/students',
    this.previousStud.id,
    this.previousStud.name,
  ]);
}

nextStudent() {
  this.router.navigate(['/students', this.nextStud.id, this.nextStud.name]);
}
  1. To prevent the button click for previous/next student which doesn't exist, you need to disable the button.
<button
  type="button"
  class="btn btn-outline-success"
  (click)="previousStudent()"
  [disabled]="!previousStud"
>
  Previous Student
</button>

<button
  type="button"
  class="btn btn-outline-success"
  (click)="nextStudent()"
  [disabled]="!nextStud"
>
  Next Student
</button>

Demo @ StackBlitz

0
Sanju Jacob Ebey On

The student's name is not changing in the route as in the previousStudent() and nextStudent() you are only updating the stdID by incrementing or decrementing and for the name you are passing this.stdNAME in both the functions. Hence the name will remain the same when you click previous student or next student. Now what you should do is that, initialize an array with the list of students in your component. I have given below a very basic logic that could be implemented, please do structure the code depending on your requirement.

 
    //For now, I am just initializing the array with static data.
   public students: Array<any> = [
    { id: 1, name: "Jake" },
    { id: 3, name: "Lando" },
    { id: 4, name: "John" },
    { id: 9, name: "Ram" }
  ];

  ngOnInit() {
     //Initialze an array with the list of students by fetching it from the server.

    // Display Student ID in the Component
    this.route.params.subscribe(data => {
    this.stdID = data['id'];
    this.stdNAME = data['name'];
    console.log(this.stdID);
    let currentIndex = students.findIndex((x) => x.id == this.stdID);
  })

}

previousStudent(){
  if(index > 0) {
  let previousID = students[currentIndex-1].id;
  let previousNAME = students[currentIndex-1].name;
  }
  //You could disable the previous button if the student being displayed is the first student in the array.
  this.router.navigate(['/students', previousID, previousNAME])
}
nextStudent(){
  if(index < students.length) {
  let nextID = students[currentIndex+1].id;
  let nextNAME = students[currentIndex-1].name;
  } else {
    //Do nothing or it's better if you could display a pagination so that the user knows that this is the last student and you could disable the next button if it's the last student that you have displayed.
  }
  this.router.navigate(['/students', nextID, nextNAME])
}

Hope this helps!