In my HTML I am using *ngFor to display my array of servers. Seriously no clue where to go from here and what I am doing wrong. I have googled for hours but couldn't find the right way to do this. Its just frustrating..
1 First Component:
@Component({
selector: 'app-server',
templateUrl: './servers.component.html',
styleUrls: ['./servers.component.css']
})
export class ServerComponent implements OnInit {
serverId: number;
serverName: string;
serverStatus: string;
constructor(id: number, name: string, status: string) {
this.serverId = id;
this.serverName = name;
this.serverStatus = status;
}
}
2 Second Component:
@Component({
selector: 'app-servers',
templateUrl: './servers.component.html',
styleUrls: ['./servers.component.css']
})
export class ServersComponent implements OnInit {
servers: Object[];
serverObj: Object;
constructor() {
this.servers = [];
this.serverObj = new ServerComponent(0, "testN", "testS");
}
createServer() {
this.servers.push(this.serverObj);
}
}
}
3 Error Message:
Compiled with problems:
ERROR
src/app/app.module.ts:12:5 - error NG6001: The class 'ServerComponent' is listed in the declarations of the NgModule 'AppModule', but is not a directive, a component, or a pipe. Either remove it from the NgModule's declarations, or add an appropriate Angular decorator.
12 ServerComponent,
~~~~~~~~~~~~~~~
src/app/server/server.component.ts:9:14
9 export class ServerComponent implements OnInit {
~~~~~~~~~~~~~~~
'ServerComponent' is declared here.
ERROR
src/app/server/server.component.ts:14:15 - error NG2003: No suitable injection token for parameter 'id' of class 'ServerComponent'.
Consider using the @Inject decorator to specify an injection token.
14 constructor(id: number, name: string, status: string) {
~~
src/app/server/server.component.ts:14:19
14 constructor(id: number, name: string, status: string) {
~~~~~~
This type is not supported as injection token.
CodePudding user response:
Component constructors are for dependency injection only. You don't normally create instances of components via JS either, you just add their tags to an html file.
If you want a class with a regular constructor, just use a regular class. If you want to then pass that data from one component to another, there a few ways to do it, depending on your use case.
I can't tell exactly what you're doing but it looks like you need both these components, so you'll need another class to hold the data.
export class Server {
serverId: number;
serverName: string;
serverStatus: string;
constructor(id: number, name: string, status: string) {
this.serverId = id;
this.serverName = name;
this.serverStatus = status;
}
}
You can then instantiate your array of servers like you were trying to do. Normally you use the ngOnInit
lifecycle hook in a component, since the constructor is mainly for DI. That's why components implement the interface by default.
@Component({
selector: 'app-servers',
templateUrl: './servers.component.html',
styleUrls: ['./servers.component.css']
})
export class ServersComponent implements OnInit {
servers: Server[] = [];
ngOnInit() {
this.servers.push(new Server(0, "testN0", "testS0"));
this.servers.push(new Server(1, "testN1", "testS1"));
this.servers.push(new Server(2, "testN2", "testS2"));
}
}
To pass a single server to every ServerComponent
you can do so by adding an @Input()
property.
@Component({
selector: 'app-server',
templateUrl: './servers.component.html',
styleUrls: ['./servers.component.css']
})
export class ServerComponent implements OnInit {
@Input() server?: Server;
ngOnInit() {
console.log(this.server);
}
}
You can also give a default value rather than using a ?
.
@Input()
allows you to input data into a component via html. ngFor*
will also let you iterate over the array, creating one component for every entry in the array.
So in servers.component.html
<app-server *ngFor="let server of servers" [server]="server"></app-server>
Square brackets indicate an input property.
This will create three instances of ServerComponent
when you instantiate a ServersComponent
.