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
getServernever returnsundefined(and specifying the return type you want explicitly is a good idea). - Handle the
undefinedcase 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[].
