4

I have searched a lot in stackoverflow but I don't find a real explanation to my problem.... I'm trying to make a simple angular2 application, with a RouterModule, a simple Service and a simple Component. So :
My Router Module :

import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { StudentListComponent } from '../students-list.component'; import { StudentComponent } from '../student.component'; const routes: Routes = [ { path: 'students', component : StudentListComponent }, { path: 'student/:id', component: StudentComponent }, { path: '**', redirectTo : '/students', pathMatch: 'full' }, { path: '', redirectTo : '/students', pathMatch: 'full' } ]; @NgModule({ imports: [ RouterModule.forRoot(routes) ], exports: [ RouterModule ] }) export class AppRouterModule { } 

My Component :

import { Component, OnInit } from '@angular/core'; import { StudentService } from './services/student.service'; import { Student } from './class/Student'; @Component({ selector: 'student-list', templateUrl: 'app/views/students-list.component.html', styleUrls: ['app/views/styles/students-list.component.css'], providers : [ StudentService ] }) export class StudentListComponent implements OnInit { private studentService: StudentService; students: Student[]; constructor(studentService: StudentService) { console.log('reinit component'); this.studentService = studentService; } ngOnInit(): void { if(!this.students) this.studentService.getStudents().then( (students) => this.students = students ); } } 

My Service :

import { Injectable } from '@angular/core'; import { Http } from '@angular/http'; import 'rxjs/add/operator/toPromise'; import { Student } from '../class/Student'; import { Note } from '../class/Note'; import { CourseService } from './course.service'; @Injectable() export class StudentService { static service: StudentService; private httpUrl = "http://localhost/NotesApp/webServ/"; private students: Student[]; private courseService: CourseService; private http:Http; constructor(courseService: CourseService, http:Http){ console.log('reinit service'); this.courseService = courseService; this.http = http; } getStudents(): Promise<Student[]> { return this .http .get(this.httpUrl+'getStudents') .toPromise() .then( response => this.hydratedStudentArray( response.json() ) ) .catch( this.handleError ); } getStudentById(id: number): Promise<Student> { return this .http .get(this.httpUrl+'getStudent/'+id) .toPromise() .then(response => this.hydratedStudent( response.json()[0]) ) .catch( this.handleError ); } private hydratedStudentArray(jsonArray: { id: number, firstname: string, lastname: string }[]): Student[]{ let hydratedArray: Student[] = []; for (let jsonElement of jsonArray){ hydratedArray.push(new Student(jsonElement.id, jsonElement.lastname, jsonElement.firstname)); } return hydratedArray; } private hydratedStudent(jsonElement: { id: number, firstname: string, lastname: string }): Student{ return new Student(jsonElement.id, jsonElement.lastname, jsonElement.firstname); } private handleError(error: any): Promise<any> { console.error('An error occurred', error); // for demo purposes only return Promise.reject(error.message || error); } } 

So my problem is : When I navigate using a link like <a routerLink="/students">Students</a> or <a [routerLink]="['/student', student.id]" >{{ student.lastname }} {{ student.firstname }}</a>, this trigger the console.log I have written in the component and service constructor..., I see 'reinit component' and 'reinit service' in my console each time I navigate ... How can I avoid this ? Thanks

3
  • 1
    You could implement a custom reuse strategy like mentioned in stackoverflow.com/questions/33940095/…. Usually a better approach is to build the components in a way, that it doesn't matter when they are destroyed when navigating away and recreated when navigating back. For example you can store the status in a shared service instead of in the component itself. Commented Feb 17, 2017 at 15:52
  • I wanted to store the students in a private property in my service, but this last become reinintialized too, like if it is not a singleton ... Are you saying this is the true functioning of angular :/ ? ... Commented Feb 17, 2017 at 16:05
  • If you provide the service on a component, it will be created and destroyed with the component. For your use case it should be provided at a parent component (then one that contains the <router-outlet> where the component is added, or provide it in @NgModule(), then it will be a singleton for the whole application and created and destroyed with the application. Commented Feb 17, 2017 at 16:14

1 Answer 1

3

The problem was here : I loaded the provider in the component itself, but it should be declared only in my NgModule, so the entire module can use it. I was re-declaring the provider in the component like this :

providers: [ StudentService ] 

and that is why the service was re-instancied each time I called the component... Thanks !

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.