I am new to Angular and was working with the Router module. Below I have a Servers component which has 3 servers and when I click on each server it opens the server's individual component(server component) is displayed in the same page. When I click on any server the server component for that server is displayed beside but it works for only 1 of the 3 servers. After a server is clicked the server's individual page is displayed beside but when we click on remaining servers the same action does not repeat for them. Please let me know why this is happening. Below is the app.module.TS ,servers.component.TS , server.component.TS and the server.component.HTMl in respective order.
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { UsersComponent } from './users/users.component';
import { ServersComponent } from './servers/servers.component';
import { UserComponent } from './users/user/user.component';
import { EditServerComponent } from './servers/edit-server/edit-server.component';
import { ServerComponent } from './servers/server/server.component';
import { ServersService } from './servers/servers.service';
import { RouterModule } from '@angular/router';
const appRoutes =[
{path:"users",component:UsersComponent,
children:[
{path:":id/:name", component:UserComponent},
]},
{path:"",component:HomeComponent},
{path:"servers", component:ServersComponent, children:[
{path:":id" , component:ServerComponent},
{path:":id/edit", component:EditServerComponent},
]
}
]
@NgModule({
declarations: [
AppComponent,
HomeComponent,
UsersComponent,
ServersComponent,
UserComponent,
EditServerComponent,
ServerComponent
],
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(appRoutes),
],
providers: [ServersService],
bootstrap: [AppComponent]
})
export class AppModule { }
Servers.component.HTML
<div >
<div >
<div >
<a
*ngFor="let server of servers"
[routerLink] = "['/servers', server.id]"
[queryParams]="{editable:1}"
fragment="loading">
{{ server.name }}
</a>
</div>
</div>
<div>
<router-outlet></router-outlet>
</div>
</div>
Server.component.TS
import { Component, OnInit } from '@angular/core';
import { ServersService } from '../servers.service';
import { Router , ActivatedRoute} from '@angular/router';
@Component({
selector: 'app-server',
templateUrl: './server.component.html',
styleUrls: ['./server.component.css']
})
export class ServerComponent implements OnInit {
server: {id: number, name: string, status: string};
id:number;
queryParamsfromURL:{queryparams:""} = {queryparams:""};
fragmentsFromURL:string=""
constructor(private serversService: ServersService, private route: ActivatedRoute) {
}
ngOnInit() {
this.id = this.route.snapshot.params['id'];
this.route.params.subscribe(
params => {this.id = params['id']}
)
this.server = this.serversService.getServer( this.id);
console.log(this.server);
//queryparams and fragments
this.queryParamsfromURL.queryparams = this.route.snapshot.queryParams['editable'];
this.route.queryParams.subscribe(
newqueryparams => {this.queryParamsfromURL = newqueryparams.editable}
);
this.fragmentsFromURL = this.route.snapshot.fragment;
this.route.fragment.subscribe(
fragmentchange => {this.fragmentsFromURL = fragmentchange}
)
}
}
Server.component.HTML
<div >
<h5> {{server.name}}</h5>
<p>Server status is {{server.status}}</p>
</div>
CodePudding user response:
Kindly try adding the href="#" attribute in the anchor tag in servers.component.html.It may work.
Servers.component.html:
<div >
<div >
<div >
<a
href="#" // try this
*ngFor="let server of servers"
[routerLink] = "['/servers', server.id]"
[queryParams]="{editable:1}"
fragment="loading">
{{ server.name }}
</a>
</div>
</div>
<div>
<router-outlet></router-outlet>
</div>
</div>
CodePudding user response:
You set up the route listener inside ngOnInit
which executes one time only. This is the root cause.
Here is the code
this.route.params.subscribe(
params => {this.id = params['id']}
)
this.server = this.serversService.getServer( this.id);
What you wanted is the serverService
get called whenever the route change, however, that piece of code is outside of the subscribe
. So the this.id
get updated but that line this.server
never get run again.
We want route changes => call the service => service invocation's code should be placed inside the subscribe
body
this.route.params.subscribe(
params => {
this.id = params['id']
this.server = this.serversService.getServer( this.id);
})