Is it possible to utilize distinctUntilKeyChanged to filter out repeated objects?

Recently delving into rxjs within Angular 7, I encountered a challenge with an API that returns user details. My goal is to filter out objects with the same name, but my attempts using distinctUntilKeyChanged() have not yielded the desired results - the console output mirrors the original API response. Additionally, I'm curious if it's possible to directly utilize the returned data from the service in the component, given that the response is already an Observable compliant with Interface specifications, without resorting to From() or Of() methods.

This quandary pertains to Angular 7 and RxJS 6, as though I've been working with Angular for a year, RxJS remains uncharted territory for me. I find myself grappling with uncertainties, such as whether I can leverage the HTTP response from the service directly within the component, or if I should implement operators to convert the response into a stream. In essence, can I work with the JSON response directly in the component while utilizing various operators like find(), first(), ignoreElements, etc...

Snippet from user.service.ts:


private urlLara = 'http://laravel.technalatus.com/public/api/'
public getusers(): Observable<User> {
  const head = new HttpHeaders({
    'Accept': 'application/json',
    'Content-Type': 'application/json',
  })
  return this.http.get<User>(this.urlLara + 'users', { headers: head });
}

Snippet from component.ts:


export class AppComponent implements OnInit {
title = 'angularrxjs';
items: {};
post: Post;
user: User;
public searchTerm: string;

constructor(private UserService: UserService) {}

ngOnInit() {
this.distinct()
}

public Duchanged() {
// custom compare for name
this.UserService.getusers().pipe(distinctUntilChanged((prev, curr) => prev.name === curr.name))
.subscribe(console.log);
}

Current Output:

[
{id: 2, name: "alshoja", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2a4b46594245404b6a4d474b434604494547">[email protected]</a>", email_verified_at: null, type: "admin"},
{id: 3, name: "Ellaware", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="6706050f0e27000a060e0b4904080a">[email protected]</a>", email_verified_at: null, type: "user"},
{id: 17, name: "alshoja", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="721132155c111d1f">[email protected]</a>", email_verified_at: null, type: "user"}
]

Desired Output:

[
{id: 2, name: "alshoja", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="98f9f4ebf0f7f2f9d8fff5f9f1f4b6fbf7f5">[email protected]</a>", email_verified_at: null, type: "admin"},
{id: 3, name: "Ellaware", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="38595a5051785f55595154165b5755">[email protected]</a>", email_verified_at: null, type: "user"},
]

Answer №1

Your understanding of how distinctUntilKeyChanged and distinctUntilChanged function is inaccurate. According to the documentation:

  • distinctUntilKeyChanged will only emit when the specified key value has changed. (Source: docs)
  • distinctUntilChanged will emit only if the current value differs from the last one. (Source: docs)

Since the name field changes in each object, it will trigger emission every time. To make distinctUntilKeyChanged or distinctUntilChanged work as desired, items should be distinctly ordered like the example below:

[
  { id: 3, name: "Ellaware", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="214043494861464c40484d0f424e4c">[email protected]</a>", email_verified_at: null, type: "user" },
  { id: 2, name: "alshoja", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8dece1fee5e2e7eccdeae0ece4e1a3eee2e0">[email protected]</a>", email_verified_at: null, type: "admin" },
  { id: 17, name: "alshoja", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="412201266f222e2c">[email protected]</a>", email_verified_at: null, type: "user" }
]

In this scenario, using distinct would be more suitable.

import { distinct, toArray } from 'rxjs/operators';

public Duchanged() {
  this.UserService.getusers()
  .pipe(
    distinct(user => user.name),
    toArray()
  )
  .subscribe(console.log);
}

Answer №2

distinctUntilChanged operator works by disregarding new values in the stream that are identical to the previous one. In this scenario, you have a stream containing an array of users with only one result.

To eliminate duplicates from your array, you can utilize the map operator along with the array's filter method.

this.UserService.getusers().pipe(
   map((users) => users.filter((v,i) => users.indexOf(v) === i))
   .subscribe(console.log);

Answer №3

distinctUntilChanged -> Ensure that only the current and previous object are checked. Before passing the JSON data, make sure to sort it based on name and then apply distinctUntilChanged();
The expected result of this.UserService.getusers() should be as follows:
[
{id: 2, name: "alshoja", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="42232e312a2d282302252f232b2b6c212d2f">[email protected]</a>", email_verified_at: null, type: "admin"},
{id: 17, name: "alshoja", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="610221064f020e0c">[email protected]</a>", email_verified_at: null, type: "user"},
{id: 3, name: "Ellaware", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="1677747e7f56717b777f7a3875797b">[email protected]</a>", email_verified_at: null, type: "user"}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I am experiencing issues with my Angular2 project where not all of my component variables are being passed to the

My problem involves sending three variables to my HTML template, but it only recognizes one of them. The HTML template I am using looks like this: <div class="page-data"> <form method="post" action="api/roles/edit/{{role?.ID}}" name="{{role? ...

After upgrading to RC.3, the Angular 2 router is failing to redirect to the correct route

I've encountered an issue with the navigate function in the router after upgrading my angular version from 2.0.0-rc.1 to 2.0.0-rc.3. As part of the upgrade, I also had to update the router version: @angular/router : 2.0.0-rc.1 to 3.0.0-alpha.7 Addit ...

The issue arises when trying to use the map function on ctorParameters, which

I recently installed Angular2CLI from Bitbucket. After running npm install, ng build, and ng serve, I encountered an error when trying to access localhost:4200. Uncaught TypeError: ctorParameters.map is not a function at ReflectionCapabilities.paramet ...

Avoid duplication of values in Angular4 when using *ngFor

Looking for assistance in updating an AngularJS project to Angular4. I have a JSON rest endpoint that returns a list of activities sorted by date and time. In AngularJS, I utilized ng-repeat to iterate through the data and ng-show to prevent duplicate entr ...

Issue: "contains method is not supported" in Ionic 2

I'm currently working on a code to validate the contents of my input field, but I've encountered an issue with using the contains function. Here's the TypeScript function I have written: checkFnameFunction(name){ if(name.contains("[a-z ...

Angular 6 issue: Bootstrap 4 carousel indicators not responsive to clicks

I am currently working on incorporating a Bootstrap 4 carousel into my application, but I seem to be encountering issues with the indicators. Ideally, clicking on any of them should navigate you to the corresponding photo, similar to this example: https:// ...

Lazy loading causes sidebar icons to become unclickable

Having an issue with lazy loading the sidebar. I am using mat-icons and have created a shared module that includes the sidebar component. However, when the icon is clicked, it does not navigate. sidebarcomponent.html <li class="nav-item"> <a ...

Angular 7: Polyfill required for npm package to support 'Class'

I am encountering an issue where my Angular 7-based app is not functioning in Internet Explorer 11. The npm package I am using begins in index.js: class PackageClass { // code } While the app works as intended in other browsers, it fails to open in ...

Facing the issue once more - Angular displaying "Http failure response for... 0 Unknown Error"

I have been researching extensively on this issue, particularly on Stack Overflow. Many of the responses point to it being a CORS problem, but I am uncertain if that is the case in my situation. Therefore, I am reaching out for help once again and would gr ...

Creating a custom Angular HTTP interceptor to handle authentication headers

Necessity arises for me to insert a token into the 'Authorization' header with every HTTP request. Thus, I created and implemented an HttpInterceptor: @Injectable() export class TokenInterceptor implements HttpInterceptor { constructor(public ...

Reference ngFor for Input Validation Template

I'm currently facing an issue with validating input fields within a *ngFor loop. I am struggling to create unique template references for each input field. Basically, I need all input fields to be required on submit unless at least one of them is fill ...

What effective method can be used to transfer data between two sibling Angular components?

I'm diving into Angular and have a question about the best approach for enabling communication between two components in my application. I know there are various strategies available and I want to figure out what would work well for my specific scenar ...

Definition of TypeScript type representing the value of a key within an object

As I delve into defining custom typings for a navigation library using TypeScript, one challenge that has me stumped is creating a navigate function. This function needs to take the Screen's name as the first argument and the Screen's properties ...

Combining union types with partial types in TypeScript: A guide

Consider the following type in TypeScript: type Input = { a: string b: number } | { c: string } How can we merge it into a partial type like this: type Result = { a?: string b?: number c?: string } We are seeking a type Blend<T>: type B ...

What is the best way to integrate this Google Dialogflow code into a TypeScript-based React application?

The integration of your chatbot into an HTML page using Google Dialogflow includes the following code snippet: <script src="https://www.gstatic.com/dialogflow-console/fast/messenger/bootstrap.js?v=1"></script> <df-messenger inten ...

The subscriber is consistently failing to return the correct value after execution, always reverting back to the default value of

I am encountering an issue with the prefillLoginId function where the value returned is always false, even though each code inside the subscription is executed. Can anyone assist me in resolving this and returning a true value? private prefillLoginId(cur ...

Is it possible for the filter with the new date() function to accept formats other than yyyy-mm-dd?

After receiving a response from mydatepicker in the specific format below: { "isRange":false, "singleDate":{ "date":{ "year":2022, "month":5, "day":13 }, "jsDate": ...

Develop an Angular 15 function that generates observables by utilizing local variables

The function being observed is not executed through HTTP; it must be a local function, but still needs to be subscribed to. Below is the implementation I came up with based on online examples: export class AppComponent implements OnInit { title = 'S ...

Obtaining a function from the Lit Element CDN bundle file within a TypeScript file

I have successfully created a compact lit element bundle file using rollup.config.js. This bundle file has been uploaded to Netstorage, and here is how my lit element is structured: import {customElement} from "lit/decorators.js"; import {LitElem ...

Distinguish among various mat accordion types

I created a custom wrapper for the mat accordion component in Angular Material to handle multiple accordions with different behaviors based on user interaction. Here is my implementation: Wrapper Mat Accordion HTML <mat-accordion> <mat-expa ...