O erro é após compilar:
ERROR in src/app/core/services/service-principal.service.ts:25:12 - error NG2003: No suitable injection token for parameter ‘base’ of class ‘ServicePrincipalService’.
Found string
public base: string
Classe
import { CrudOperations } from ‘./crudoperations.interface’;
import { HttpClient } from '@angular/common/http';
import {
ActivatedRoute,
Router
} from '@angular/router';
import { Injectable } from '@angular/core';
import { CLINICA_MEDICA_API } from './clinicamedica.api';
import pickBy from 'lodash/pickBy';
import isArray from 'lodash/isArray';
import isEmpty from 'lodash/isEmpty';
import isUndefined from 'lodash/isUndefined';
import isNull from 'lodash/isNull';
import trim from 'lodash/trim';
@Injectable({
providedIn: 'root'
})
export class ServicePrincipalService<T, ID> implements CrudOperations<T, ID> {
constructor(
public httpClient: HttpClient,
public activatedRoute: ActivatedRoute,
public router: Router,
public base: string
) {}
public incluir(t: T) {
return this.httpClient.post(`${CLINICA_MEDICA_API}` + this.base + '/incluir', t);
}
public alterar(t: T) {
return this.httpClient.put(`${CLINICA_MEDICA_API}` + this.base + '/alterar', t);
}
public excluir(id: ID) {
return this.httpClient.delete(`${CLINICA_MEDICA_API}` + this.base + '/excluir/' + id);
}
public pesquisar(p: T) {
const params: any = this.removerUndefinedEmptyNull(p);
this.updateURLComParametrosDePesquisa(p);
return this.httpClient.get(`${CLINICA_MEDICA_API}` + this.base + '/pesquisar', { params });
}
public buscar(id: ID) {
return this.httpClient.get(`${CLINICA_MEDICA_API}` + this.base + '/buscar/' + id);
}
private removerUndefinedEmptyNull(parameters: any) {
const res = pickBy(parameters,
// tslint:disable-next-line:only-arrow-functions
function(value: any) {
let definido: boolean;
if (isArray(value)) {
definido = !isEmpty(value);
} else {
definido = !isUndefined(value) && !isNull(value) && !isEmpty(trim(value));
}
return definido;
}
);
return res;
}
private updateURLComParametrosDePesquisa(parametros: any) {
this.router.navigate([], { relativeTo: this.activatedRoute, queryParams: parametros });
}
}
Boa noite Guilherme,
Eu acho que você terá que criar um InjectionToken. Porque base
é uma string, que é um tipo primitivo e o DI não consegue distingui-lo, então esse Token fará o papel de distinguir esse cara q vc precisa dos outros.
Dependency providers - Non-class dependencies
Power of Angular Dependency Injection - Obs.: Esse conteúdo aqui eu confesso que não li com atenção, somente dei uma olhada bem por cima… Mas, eu vi que em algum ponto ele cria diversos token’s e achei que, talvez, seja mais ou menos oq você precisa.
A base é o endereço que o cliente irá acessar o endpoint do servidor.
Exemplos:
-
se estou na tela de cliente e n servidor o endpoint é cliente, O angular passa isto como parâmetro, para o servico ser acessado.
-
se estou na tela de venda e n servidor o endpoint é venda, O angular passa isto como parâmetro, para o servico ser acessado.
Não entendi porque está dando erro
Ele dá erro justamente por seu componente ser injetável e o responsável por resolver as injeções de dependências não conseguir resolver uma string.
A documentação do Angular, fala exatamente sobre o que você está tentando fazer:
Not all dependencies are classes. Sometimes you want to inject a string, function, or object.
Apps often define configuration objects with lots of small facts, like the title of the application or the address of a web API endpoint. These configuration objects aren’t always instances of a class. They can be object literals, as shown in the following example.
Eu achei um tópico no Stackoverflow, que aparenta ser algo bem semelhante a sua implementação: Angular: How to send a string to an injection service?
Não sei se ficou claro o motivo pelo qual isso apresenta um erro. Mas, basicamente, é justamente pela sua classe ter a dependência de uma string.
Troquei de string para String e funcionou. Qual é a diferença ?
import { CrudOperations } from './crudoperations.interface';
import { HttpClient } from '@angular/common/http';
import {
ActivatedRoute,
Router
} from '@angular/router';
import { Injectable } from '@angular/core';
import { CLINICA_MEDICA_API } from './clinicamedica.api';
import pickBy from 'lodash/pickBy';
import isArray from 'lodash/isArray';
import isEmpty from 'lodash/isEmpty';
import isUndefined from 'lodash/isUndefined';
import isNull from 'lodash/isNull';
import trim from 'lodash/trim';
@Injectable({
providedIn: 'root'
})
export class ServicePrincipalService<T, ID> implements CrudOperations<T, ID> {
constructor(
public httpClient: HttpClient,
public activatedRoute: ActivatedRoute,
public router: Router,
public base: String
) {}
public incluir(t: T) {
return this.httpClient.post(`${CLINICA_MEDICA_API}` + this.base + '/incluir', t);
}
public alterar(t: T) {
return this.httpClient.put(`${CLINICA_MEDICA_API}` + this.base + '/alterar', t);
}
public excluir(id: ID) {
return this.httpClient.delete(`${CLINICA_MEDICA_API}` + this.base + '/excluir/' + id);
}
public pesquisar(p: T) {
const params: any = this.removerUndefinedEmptyNull(p);
this.updateURLComParametrosDePesquisa(p);
return this.httpClient.get(`${CLINICA_MEDICA_API}` + this.base + '/pesquisar', { params });
}
public buscar(id: ID) {
return this.httpClient.get(`${CLINICA_MEDICA_API}` + this.base + '/buscar/' + id);
}
private removerUndefinedEmptyNull(parameters: any) {
const res = pickBy(parameters,
// tslint:disable-next-line:only-arrow-functions
function(value: any) {
let definido: boolean;
if (isArray(value)) {
definido = !isEmpty(value);
} else {
definido = !isUndefined(value) && !isNull(value) && !isEmpty(trim(value));
}
return definido;
}
);
return res;
}
private updateURLComParametrosDePesquisa(parametros: any) {
this.router.navigate([], { relativeTo: this.activatedRoute, queryParams: parametros });
}
}
1 curtida
string
: é um tipo primitivo.
String
: é um objeto/tipo por referencia.
Confesso que não sabia da existência dos dois no Angular. Mas, se formos pensar no JAVA, o funcionamento é idêntico.
Essa troca funcionou pois, String
é um objeto/uma classe(também conhecido com tipo complexo) e não um tipo primitivo e então o DI consegue identifica-lo e dar a devida tratativa, oque ele não conseguiria fazer usando um tipo primitivo e então, você precisaria de um InjectionToken
.
1 curtida