import {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} from "@angular/router";
import {Observable} from "rxjs";
import {ServersService} from "../servers.service";
import {Injectable} from "@angular/core";
interface Server {
id: number,
name: string,
status: string
}
@Injectable()
export class ServerResolverService implements Resolve<Server> {
constructor(private serverService: ServersService) {
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Server> | Promise<Server> | Server {
let id = route.params['id'] | 1;
let server = this.serverService.getServer(id);
return server; // error here in Angular 13
}
}
The code looks correct but WebStorm is spitting this error
error TS2322: Type '{ id: number; name: string; status: string; } | undefined' is not assignable to type 'Server | Observable | Promise'. Type 'undefined' is not assignable to type 'Server | Observable | Promise'.
The ServerService file looks like
export class ServersService {
private servers = [
{
id: 1,
name: 'Productionserver',
status: 'online'
},
{
id: 2,
name: 'Testserver',
status: 'offline'
},
{
id: 3,
name: 'Devserver',
status: 'offline'
}
];
getServers() {
return this.servers;
}
getServer(id: number) {
const server = this.servers.find(
(s) => {
return s.id === id;
}
);
return server;
}
updateServer(id: number, serverInfo: { name: string, status: string }) {
const server = this.servers.find(
(s) => {
return s.id === id;
}
);
if (server) {
server.name = serverInfo.name;
server.status = serverInfo.status;
}
}
}
CodePudding user response:
ServersService.getServer
's return type includes undefined
, because it just returns the result of find
which can be undefined
. E.g. what do you expect to be returned if you call this.serverService.getServer(5)
?
So you can handle this in two ways:
- Make sure
getServer
never returnsundefined
(and specifying the return type you want explicitly is a good idea). - Handle the
undefined
case insideresolve
.
CodePudding user response:
In your ServerService
, I cant see that the type Server
is defined. If it is not, please define the type there and assign it to your array as follows, then simply import the interface in your resolver:
export interface Server {
id: number,
name: string,
status: string
}
export class ServersService {
private servers: Server[] = [ //here
{
id: 1,
name: 'Productionserver',
status: 'online'
},
{
id: 2,
name: 'Testserver',
status: 'offline'
},
{
id: 3,
name: 'Devserver',
status: 'offline'
}
];
getServers() {
return this.servers;
}
getServer(id: number) {
const server = this.servers.find(
(s) => {
return s.id === id;
}
);
return server;
}
updateServer(id: number, serverInfo: { name: string, status: string }) {
const server = this.servers.find(
(s) => {
return s.id === id;
}
);
if (server) {
server.name = serverInfo.name;
server.status = serverInfo.status;
}
}
}
Is it certain that getServer
always returns a server? or the id can also result into undefined
? If the id is always valid, please try defining the return type for your getServer
method in ServerService
:
getServer(id: number): Server {
const server = this.servers.find(
(s) => {
return s.id === id;
}
);
return server;
}
Also, define the type for your variable here:
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Server> | Promise<Server> | Server {
let id = route.params['id'] | 1;
let server: Server = this.serverService.getServer(id); // here
return server; // error here in Angular 13
}
Perhaps this removes the error. In short, as I see, Server
interface is only defined in your resolver service, but your servers array in ServerService
is not of type Server[]
.