retrieve a shared string from an array when toggled

Regarding the use of SelectionModel for mat-checkbox, a function is called on each click:

 toggleSelection(row) {
    this.selection.toggle(row);
    console.log("Selection");
    console.log("this", this.selection.selected);
    this.selection.selected.forEach(selected => {
      this.masterPossibleActions = this.masterPossibleActions.filter(action => selected.possibleActions == action);
    });
    console.log(":MAster",this.masterPossibleActions)
  }

The array returned by this.selection.selected represents the selected rows and contains objects with a property called possibleActions. The goal is to have the masterPossibleActions Array contain the list of possible actions that are common between all selected rows.

Definition of PossibleAction object class:

class ActionObject {
  key: string;
  value: string;
  constructor(key: string, value: string) {
    this.key = key;
    this.value = value;
  }
}

The toggle function:

 <td mat-cell *matCellDef="let row">
          <mat-checkbox appClickStopPropagation (change)="toggleSelection(row)" class="custom-checkbox"
            [checked]="selection.isSelected(row)" [aria-label]="checkboxLabel(row)">
          </mat-checkbox>
        </td>

This.selection is defined as:

  selection = new SelectionModel<Enrolment>(true, []);

Definition of Enrolment object:

 export class Enrolment {
  id: string;
  user: any;
  enrollable: any;
  time_created: string;
  status: string;
  possibleActions: Array<ActionObject> = [];

  preparePossibleActions() {
    this.possibleActions = [];
    this.possibleActions.push(new ActionObject("DELETE", "Delete"));
    switch (this.status) {
      case "PENDING":
        this.possibleActions.push(new ActionObject("REMOVE", "Reject"));
        this.possibleActions.push(new ActionObject("APPROVE", "Approve"));
        break;
      case "REJECTED":
      case "CANCELLED":
      case "WITHDRAWN":
        break;
      case "APPROVED":
      case "WITHDRAW_PENDING":
      case "COMPLETED":
        this.possibleActions.push(new ActionObject("REMOVE", "Withdraw"));
        break;
      default:
        break;
    }
  }
  constructor(rawObj: any) {
    this.id = rawObj.id;
    this.user = rawObj.user;
    this.enrollable = rawObj.enrollable;
    this.time_created = rawObj.time_created;
    this.status = rawObj.status;
    this.preparePossibleActions();
  }
}

Answer №1

It seems like the issue at hand is how to properly filter data. One approach you could take is:

// masterPossibleActions consists of combined actions from all rows (array)
// this.selection.selected represents all selected rows (need to consider possibleActions)
let actions = this.selection.selected.map(selectedRow => selectedRow.possibleActions)
// set masterPossibleActions with first element -> can only shrink, not grow because there won't be any actions outside of the common ones in the first element
this.masterPossibleActions = actions[0]
// filter the initial value to contain only common actions
this.masterPossibleActions = this.masterPossibleActions.filter(action => {
  let isCommon = true
  actions.forEach(rowActions => {
    if (rowActions.indexOf(action) < 0 ) {
      isCommon = false
    }
  })
  return isCommon
})

final function:

 toggleSelection(row) {
    this.selection.toggle(row);
    this.masterPossibleActions = actions[0]
    this.masterPossibleActions = this.masterPossibleActions.filter(action => {
      let isCommon = true
      actions.forEach(rowActions => {
        if (rowActions.indexOf(action) < 0 ) {
           isCommon = false
        }
      })
      return isCommon
    })
  }

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

The validation process in Redux forms

Imagine we have the following types defined: interface MyFormFields { FirstName: string; LastName: string; } type FieldsType = keyof MyFormFields; const field1: FieldsType = "c"; const field2 = "c" as FieldsType; Now, I am looking to implemen ...

Passing a custom data type from a parent component to a child component in React

I'm currently working on developing a unique abstract table component that utilizes the MatTable component. This abstract table will serve as a child element, and my goal is to pass a custom interface (which functions like a type) from the parent to t ...

The Angular component seems to be lacking a template

During the upgrade process of my Angular 8 app to Angular 9, I encountered an error message while trying to build: ERROR in component is missing a template The issue is that it doesn't specify which specific component is missing a template. Is there ...

Transmit information from child to parent as needed using @input and @output in Angular 2

Is there a way to pass an object from child to parent without relying on @viewChild or services? export class MultiSelectComponent implements OnInit { selectedItems: FormSelectComponentOption[] = []; @Input() items: FormSelectComponentOption[]; @Output ...

Display the map using the fancybox feature

I have added fancybox to my view. When I try to open it, I want to display a map on it. Below is the div for fancybox: <div id="markers_map" style="display:none"> <div id="map_screen"> <div class="clear"></div> </div&g ...

How to access enums dynamically using key in TypeScript

export enum MyEnum{ Option1, Option2, Option3 } string selection = 'Option1'; MyEnum[selection] results in an error: The type string cannot be assigned to the type MyEnum On the other hand: MyEnum['Option1'] works as ...

Modifying the values of various data types within a function

Is there a more refined approach to enhancing updateWidget() in order to address the warning in the else scenario? type Widget = { name: string; quantity: number; properties: Record<string,any> } const widget: Widget = { name: " ...

employing constructor objects within classes

I am attempting to utilize a class with a constructor object inside another class. How should I properly invoke this class? For example, how can I use Class 1 within Class 2? Below is an instance where an object is being created from a response obtained f ...

What is the best way to align text alongside icons using ng-bootstrap in Angular 8?

I have a set of four icons positioned next to each other, but I want them to be evenly spaced apart. I tried using the justify-content-between class, but it didn't work. How can I achieve this? I'm creating a Progressive Web App (PWA) for mobile ...

How does one distinguish between the uses of "any" and "any[ ]"?

Exploring the Difference Between any and any[ ] An Illustrative Example (Functioning as Expected) variable1: any; variable2: any[]; this.variable1 = this.variable2; Another Example (Also Functioning as Intended) variable1: any; v ...

The error message "Property 'originalUrl' is not found in type 'Request<ParamsDictionary, any, any, ParsedQs, Record<string, any>>'" appeared

In my TypeScript project, I am utilizing a gulpfile to initiate the process. Within the gulpfile, I am using express where I encounter an issue while trying to access req.originalUrl, with req being the request object. An error is thrown stating Property ...

Error 2300 in Vetur: Identical identifier found for '(Missing)'

Recently, I've been encountering a strange issue with Vetur in my typescript nuxt.js project. Every component, whether it's just an empty line or contains code, displays an error message on the first line. I can't pinpoint when this problem ...

Establish a connection between two pre-existing tables by utilizing the Sequelize framework

I have two tables already set up (User and PaymentPlan), but they were not initially linked together. PaymentPlan.ts import { DataTypes, Model } from "sequelize"; import { sequelize } from "./DBConnections/SequelizeNewConnection"; exp ...

Executing multiple HTTP requests in Angular using the HttpClient

Recently, I came across a concerning issue in my Angular 5 App. It all started with this simple call in my service: interface U{ name:string; } ... constructor(private http : *Http*, private httpC:HttpClient) // Http is deprecated - its a compare test ...

What would cause the nsfw property to be absent from a TextChannel in client.on("messageCreate") event?

Currently working with Typescript in combination with Discord.js v14, I'm encountering the following error: Property 'nsfw' does not exist on type 'DMChannel | PartialDMChannel | ... Below is the snippet of problematic code: client.on( ...

I've noticed that the list item vanishes unexpectedly when utilizing Primeng drag-and-drop feature

Whenever I try to drag an item from one list to another in the Primeng picklist, the item disappears until it is dropped. <p-dialog [(visible)]="showMarker" (onHide)="hideDialogChild()" [contentStyle]="{'overflow':'visible'}" h ...

Looping through two arrays of objects using Angular's NgFor directive

I need to iterate through two separate arrays using ngFor in order to display their content in an html format. <div class="form-check ml-5" *ngFor="let item of competencias.competencias; let i = index"> <input class=" ...

The current version of NPM - typescript is 2.2.2, and we are unable to update it to 2.4.1 due to it being a symlink

While attempting to install TypeScript through NPM, I encountered the error below. Can you help me identify the issue? Command: npm install typescript Error: The installation of TypeScript failed because it requires an update from version 2.2.2 to 2.4. ...

sort the array based on its data type

Recently diving into typescript... I have an array that is a union of typeA[] | typeB[] but I am looking to filter based on the object's type interface TypeA { attribute1: string attribute2: string } interface TypeB { attribute3: string attri ...

Event listener for scrolling in Angular Dart component

I am looking to implement a functionality where a "back to top" button appears once the user has scrolled the page by 500px. I have been trying to capture the scroll event in the main Div of my AppComponent. <div class="container" scrollable&g ...