A guide on combining multiple arrays within the filter function of arrays in Typescript

Currently, I am incorporating Typescript into an Angular/Ionic project where I have a list of users with corresponding skill sets. My goal is to filter these users based on their online status and skill proficiency.

[
        {
            "id": 1,
            "name": "Vikram Shah",
            "online_status": "Online",
            "skills": [{
                    "id": 2,
                    "title": "CSS"
                },
                {
                    "id": 3,
                    "title": "JavaScript"
                },
                {
                    "id": 4,
                    "title": "Python"
                }
            ]
        },

        {
            "id": 1,
            "name": "Abhay Singh",
            "online_status": "Online",
            "skills": [{
                    "id": 1,
                    "title": "HTML"
                },
                {
                    "id": 2,
                    "title": "CSS"
                },
                {
                    "id": 3,
                    "title": "JavaScript"
                },
                {
                    "id": 4,
                    "title": "Python"
                }
            ]
        },

        {
            "id": 1,
            "name": "Test Oberoi",
            "online_status": "Online",
            "skills": [{
                    "id": 1,
                    "title": "HTML"
                },
                {
                    "id": 2,
                    "title": "CSS"
                },
                {
                    "id": 3,
                    "title": "JavaScript"
                },
                {
                    "id": 4,
                    "title": "Python"
                }
            ]
        }
    ]

The provided array showcases different skills each user possesses

 this.skill_types = [
      {"id":8,"title":"Cleaner", checked:false},
      {"id":7,"title":"Painter", checked:false},
      {"id":6,"title":"Plumber", checked:false},
      {"id":5,"title":"Carpenter", checked:false},
      {"id":4,"title":"Advisor", checked:false},
      {"id":3,"title":"Team Leader", checked:false},
    {"id":2,"title":"Management", checked:false},
    {"id":1,"title":"Administrator", checked:false}
   ];

This array holds the IDs of skills that need filtering

filterArr = [1, 3, 6];

My current approach works effectively with dual filtering criteria. However, I encountered issues when attempting to implement a secondary filter condition. The secondary filter should be active only when 'filterArr' is not empty.

return this.items = this.items.filter((thisUser) => {
        return thisUser.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1 &&
       thisUser.skills.some(c => this.filterArr.includes(c.id))
      });

The primary issue arises when no skill is selected for filtering; my intention is to display all users under such circumstances. Unfortunately, the logic in place does not function as intended. Ideally, no filters should apply if there are selected skills (filter conditions). I attempted an adjustment, but it led to further complications.

  let filteredByStatus = [];
  filteredByStatus = this.items.filter((thisUser) => {
    return thisUser.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1
  });

  //Condition can be applied if filtering is separated
  let filteredBySkills = [];
  filteredBySkills = this.items.filter((thisUser) => {
    return thisUser.skills.some(c => this.filterArr.includes(c.id))
  });

  //Expecting to join results from multiple filters
  return this.items = filteredByStatus.concat(filteredBySkills);

Unfortunately, the revised code snippet fails to deliver the expected outcome. I am seeking a solution to seamlessly merge arrays of similar objects without duplicating them.

Answer №1

Instead of combining arrays for filtering, consider using rxjs filter in your code.

return from(this.items)
    .pipe(
      filter(user => {
        return user.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1 
                && user.skills.some(c => filterArr.includes(c.id));
      })
    );

If you prefer to separate it out, you can modify the code like this:

return from(this.items)
    .pipe(
      filter(user => user.online_status.toLowerCase().indexOf(onlineStatus.toLowerCase()) > -1),
      filter(user => user.skills.some(c => filterArr.includes(c.id)))
    );

Check it out on Stackblitz: https://stackblitz.com/edit/angular-pk3w8b

Answer №2

If you adjust your condition slightly and include !this.filterArr.length within it (along with the user status as an OR condition), your entire condition will become true, allowing the user to receive the filter.

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

"Resulting in 'undefined' due to an asynchronous function call

Encountering an issue with async method implementation. In my authServices, there is a loginWithCredential function which is asynchronous: async loginWithCredential(username, password){ var data = {username: username, password: password}; api.pos ...

How to Properly Initialize a Variable for Future Use in a Component?

After initializing my component, certain variables remain unassigned until a later point. I am seeking a way to utilize these variables beyond the initialization process, but I am unsure of how to do so. Below is my attempted code snippet, which throws a ...

Unable to add chosen elements to array - Angular material mat select allowing multiple selections

Can anyone assist me in figuring out what I am doing wrong when attempting to push data to an empty array? I am trying to only add selected values (i.e. those with checked as true), but I can't seem to get inside the loop This is the current conditi ...

Transform webservice data into TypeScript object format, ensuring mapping of objects from capital letters to camel case

Something peculiar caught my attention in my Angular2 TypeScript project. When objects are fetched from a web service, they have the type "Level" and the properties are in Pascal case. However, during runtime, I noticed that the properties of these Levels ...

Ways to differentiate between the sources of two cold Observables (not just the possible data streams they may produce)

Situation: Within my Angular application, I am using publishReplay to store and replay specific Http requests. However, I encountered an issue where I need the cached observable source to update itself and create a new cached observable with publishReplay ...

Using Material UI with React and TypeScript

I need some assistance with organizing my menus correctly in React using TypeScript. Currently, they are displaying on top of each other instead of within their respective category menus. I have been struggling to find a solution and would appreciate any h ...

Exploring the world of TypeScript type mappings

I'm currently working on enhancing a function with type annotations. This particular function takes an array of typed objects as parameters and returns a mapped array of a different type: const createAnimals = <T extends AnimalFactory<any>[]& ...

Return the subclass from the constructor function

class X{ constructor(input: string) { // do things } f() {console.log("X")} } class Y extends X{ constructor(input: string) { // do things } f() {console.log("Y")} } class Z extends X{ con ...

Encountering the 'Default setting for timestampsInSnapshots now set to true' error in Firestore console

Encountering a Firestore error in the console while using Angular. @firebase/firestore: Firestore (5.8.3): The timestampsInSnapshots setting now defaults to true and does not require explicit setting. It is advised to remove it from firestore.settings( ...

Delay the Ngrx effect by 2 seconds before initiating the redirect

I have an ngrx effect that involves calling an HTTP method and then waiting for 2 seconds before redirecting to another page. However, the current behavior is that it redirects immediately without waiting. confirmRegistration$ = createEffect(() => { ...

Encountering Compilation Error When Using RxJS Observable with Angular 6 and Swagger Codegen

Encountering TypeScript compiler errors related to rxjs while working with Angular 6 and Swagger Codegen: Cannot find module 'rxjs-compat/Observable' Referenced the following link for assistance: https://github.com/ReactiveX/rxjs/blob/master/M ...

Exploring the world of mouse events in Typescript using JQuery, all the while maintaining strict typing regulations

I'm currently working on a project that involves using JQuery in Typescript. One challenge I'm facing is passing a mouse event from a JQuery element to a wrapper class. Here's an example of what I'm trying to achieve: import * as $ fro ...

Having trouble reaching the elements stored in an array?

As a beginner in Angular and JavaScript, I may be making some obvious mistakes so please bear with me. I have written this code that allows the selection of 2 text files and then combines them into a single array. $scope.textArray = []; $scope.textUpload ...

Obtaining radio button values from user input forms in Angular

I need help with retrieving values from a user input form. The first option is a select dropdown, the third one is a time picker which are both working fine. However, I'm struggling with the second option, which is a radio button group with two button ...

How can I make sure that another function will only be executed after the completion of a function in

I'm currently working on an app with Angular CLI, and I am trying to retrieve a list after an insertion. Despite trying various methods such as observer, promise, async, setTimeout, etc., I haven't been able to find the right solution yet. I feel ...

Make sure PTable maintains a horizontal layout on any device with PrimeNG

When I view my Ptable on desktop or iPad, it looks like this: https://i.stack.imgur.com/ONqZV.png However, when I switch to a device like an iPhone X, it changes to this layout: https://i.stack.imgur.com/H2q7j.png I want the horizontal layout to displa ...

Trouble occurs in the HTML code when trying to access a property from an inherited interface in Angular

Currently, I am working with Angular 17 and have encountered a specific query: In my project, there is an IDetails interface containing certain properties: export interface IDetails { summary: Summary; description: string; } Additionally, there is an ...

Error in Typescript: Unable to locate module with proper type declarations

Recently embarking on a new nodejs project with typescript, I utilized Typings (https://github.com/typings/typings) to install reference files for node v4.x and express v4.x. Outlined in my setup are the following versions: Node - v4.2.6 Typescript - v1 ...

A guide to activating tag selection within the DevExtreme tag box

I'm currently utilizing devExtereme within my Angular project. My goal is to enable the selection of text within tags in my tagbox component. Here's what I have implemented: <dx-tag-box [dataSource]="sourves" [value]="value&quo ...

Erase Typescript Service

To remove a PostOffice from the array based on its ID, you can use a checkbox to select the desired element and then utilize its ID for the delete function. Here is an example: let postOffices = [ {postOfficeID: 15, postCode: '3006&ap ...