0

I have a web api (.NET Core 3.1) that returns a json like the following:

[
    {
        "counterparty": "Santander",
        "tradeDate": "2020-05-23T10:03:12",
        "isin": "DOL110",
        "typology": 0
    },
    {
        "counterparty": "Jordan Banks",
        "tradeDate": "2020-06-11T11:23:22",
        "isin": "LIT250",
        "typology": 0
    },
    {
        "counterparty": "Santander",
        "tradeDate": "2020-06-11T11:24:08",
        "isin": "LIT300",
        "typology": 0
    }
]

I consume this web api with the component and angular service below. So far, I return the counterparty field of all objects.

operations.component.ts:

import { Component, OnInit } from '@angular/core';
import { OperationsService } from "./operations.service";

@Component({
  selector: 'app-operations',
  templateUrl: './operations.component.html',
  styleUrls: ['./operations.component.css']
})
export class OperationsComponent implements OnInit {

  data: any;

  constructor(private operationsService: OperationsService) { }

  ngOnInit(): void {
    this.loadOperations();
  }

  loadOperations() {
    return this.operationsService.getOperations().subscribe(source => this.data = source);
  }
}

operations.component.html:

<div *ngFor="let item of data">
  <div>{{item.counterparty}}</div>
</div>

operations.service.ts:

import { Injectable, Inject } from "@angular/core";
import { HttpClient } from "@angular/common/http";

@Injectable({
  providedIn: "root"
})
export class OperationsService {

  constructor(private http: HttpClient) { }

  public getOperations() {
    return this.http.get("https://localhost:44329/api/operations");
  }
}

app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { RouterModule } from '@angular/router';

import { AppComponent } from './app.component';
import { NavMenuComponent } from './nav-menu/nav-menu.component';
import { HomeComponent } from './home/home.component';
import { LoginComponent } from './user/login/login.component';
import { OperationsComponent } from './operations/operations/operations.component';

@NgModule({
  declarations: [
    AppComponent,
    NavMenuComponent,
    HomeComponent,
    LoginComponent,
    OperationsComponent
  ],
  imports: [
    BrowserModule.withServerTransition({ appId: 'ng-cli-universal' }),
    HttpClientModule,
    FormsModule,
    RouterModule.forRoot([
      { path: '', component: HomeComponent, pathMatch: 'full' },
      { path: 'api/operations', component: OperationsComponent }
    ])
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

what i need now is to apply a filter in the counterparty field to return only the distinct values, that is, without repetitions of equal values. I'm trying with ng-repeat, but i have the error:

Uncaught Error: Template parse errors: The pipe 'unique' could not be found ("]item of data | unique: item.counterparty"> {{item.counterparty}} ")

So, how can I get the distinct values of the array? Can I do it only in component.html or do I also have to change component.ts?

2
  • You must have forgottten to include some code because the error doesnt seems related to what you are showing. And yes you should to it in the ts. Commented Jun 11, 2020 at 15:13
  • Do you have custome pipe as unique? Commented Jun 11, 2020 at 15:16

2 Answers 2

2

I think it's best to make your this.data array unique in component.ts, then just display it in component.html.

You can use another function with promise to make data array unique, based on 'counterparty'.

 // make data array unique
codeToMakeItUnique = dataArr => {
    return new Promise((resolve, reject) => {
        const UniArr = []
        const map = new Map()
        for (const item of dataArr) {
            if (!map.has(item.counterparty)) {
                map.set(item.counterparty, true) // set any value to Map
                UniArr.push(item)
            }
        }
        resolve(UniArr)
    })
}

so altogether your component.ts will look like:

import { Component, OnInit } from '@angular/core';
import { OperationsService } from "./operations.service";

@Component({
    selector: 'app-operations',
    templateUrl: './operations.component.html',
    styleUrls: ['./operations.component.css']
})
export class OperationsComponent implements OnInit {

    data: any;

    constructor(private operationsService: OperationsService) { }

    ngOnInit(): void {
        this.loadOperations();
    }

    loadOperations() {
        return this.operationsService.getOperations().subscribe(async source => {
            this.data = await this.codeToMakeItUnique(source)
        });

        // make data array unique
        codeToMakeItUnique = dataArr => {
            return new Promise((resolve, reject) => {
                const UniArr = []
                const map = new Map()
                for (const item of dataArr) {
                    if (!map.has(item.counterparty)) {
                        map.set(item.counterparty, true) // set any value to Map
                        UniArr.push(item)
                    }
                }
                resolve(UniArr)
            })
        }
    }
}

In your component.html you can simply call your data array itself

<div *ngFor="let item of data">
  <div>{{item.counterparty}}</div>
</div>

Hope this helps.

Sign up to request clarification or add additional context in comments.

Comments

1

The question isnt clear but if you want to remove duplicated value from your array, cast it as a set then back to an array. That is if the array doesnt contains complex objects

  loadOperations() {
    return this.operationsService.getOperations().subscribe(source => this.data = Array.from(new Set(source.map((item: any) => item.counterparty))));
  }

This is going to give you [ "Santander", "Jordan Banks" ]

3 Comments

In the field counterparty, I havee 3 registers in the database: "Santander", "Jordan Banks", "Santander". I want to apply a filter that returns only unique values for the counterparty, therefore, or the expected result of this serious filter: "Snatander", "Jordan Banks". Was I clearer?
So what is the expected result? just: ['Santander', 'Jordan Banks']?
Yes...eliminate repeated counterparts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.