angular - Como filtrar dados duplicados da resposta HTTP ao exibir no lado do cliente?
Como filtramos os dados duplicados? Estou recebendo a seguinte resposta:
{username:'patrick',userid:'3636363',position:'employee'}
{username:'patrick',userid:'3636363',position:'employee'}
{username:'patrick2',userid:'3636365',position:'manager'}
Estou tentando exibir apenas
{username:'patrick',userid:'3636363',position:'employee'}
{username:'patrick2',userid:'3636365',position:'manager'}
meu componente:
onSubmit(data:string){
this.http.post(this.Url+'Employee?name='data.name,data).subscribe(res=>{
this.result=filterDuplicate(Object.values(res));
});
function filterDuplicate(users:any):any{
return users.filter(user,index)=>findIndex((u)=>user.username===u.username)===index);
}
}
html
<div *ngFor="let item of result |employee:'userId'">
{{item.userid}} {{item.username}}{{item.position}}
</div>
Eu tentei usar this.result=Array.from(new Set(res.map(value => value.userid))); mas deu erro property 'map' does not exist on type 'Object' Eu também tentei criar um pipe
declare var _: any;
@Pipe({
name: 'employee',
pure: false
})
@Injectable()
export class EmployeePipe implements PipeTransform {
transform(value: any, args: any): any {
return _.uniqBy(value, args);
}
}
Ao usar pipe, estou recebendo Erro ReferenceError: _ não está definido Qualquer ajuda será muito apreciada para listar os valores distintos.
res result:
>0:{username:'patrick',userid:'3636363',position:'employee'}
>1:{username:'patrick',userid:'3636363',position:'employee'}
>2:{username:'patrick2',userid:'3636365',position:'manager'}
Resposta #1
Editar: Se o seu res for um objeto, você pode querer convertê-lo para um array primeiro
const users = Object.values(res);
Se você tiver um array de objetos de usuário como este:
const users: User[] = [
{ username: 'patrick', userid: '3636363', position: 'employee' },
{ username: 'patrick', userid: '3636363', position: 'employee' },
{ username: 'patrick2', userid: '3636365', position: 'manager' }
];
Você pode filtrar o array para conter apenas usuários únicos usando esta função (supondo que cada usuário seja identificado por um nome de usuário único)
function filterDuplicateUsers(users: User[]): User[] {
return users.filter((user, index) => users.findIndex(
u => user.username === u.username
) === index);
}
Uma pergunta semelhante foi postada aqui.
Eu esperaria que algo assim funcionasse:
this.http.post(`${this.Url}Employee?name=${data.name}`, data).subscribe(res => {
this.result = filterDuplicateUser(Object.values(res));
});
Resposta #2
A legibilidade no fluxo/métodos lógicos principais, invocando complexidade de código isolada em métodos abstraídos, ajuda na solução de problemas, na modificação e no trabalho com outras pessoas.
Esta resposta é apenas um pouco diferente da do nah0131. Minha preferência seria usar um pipe e que a responsabilidade da inscrição seja apenas atribuir os valores. Além disso, definitivamente use a interface User sugerida na outra resposta - eu apenas mantive simples conforme a pergunta original.
Não tenho certeza de qual método filterDuplicateUsers é mais eficiente, então você pode trocar qualquer um deles por esta solução. Ambos os métodos abstratos são imutáveis, então poderiam ser usados em algum outro contexto dentro do mesmo componente mais tarde.
onSubmit(data:string) {
this.http.post(this.Url+'Employee?name='data.name,data)
.pipe(map(this.filterDuplicateUsers))
.subscribe(res => {
this.result = res;
});
}
private filterDuplicateUsers(users: any[]) {
return users.filter(({ userid: oId }, oIndex) =>
!users.some(({userid: iId}, iIndex) => oIndex > iIndex && oId === iId)
);
}
