Home > Software engineering >  Find element in an array of object with key array types
Find element in an array of object with key array types

Time:09-16

I would like to extract all active modules and actions with given roles.

getAvailableModulesAndActionsWithRoles(roles: string[]): IHubModule[] {
    const modules = [...this.getModules()];
    const activeModules = modules.filter(module => module.isEnabled);
    activeModules.map(module => {
      Object.keys(module.actions).map(action => {
        roles.map(role => {
          if (!module.actions[action]?.includes(role)) {
            delete module.actions[action];
             return;
          }
        });
      });
    });
    return activeModules;
  }

Here is how my module interface looks like

export interface IHubModule {
  name: ModuleName;
  isEnabled: boolean;
  actions: Record<Topic, string[]>;
}

I passed an array of roles as an argument and I would like to extract all active actions for a given roles.

Here is how my test looks like

it('returns only active modules and actions for a list of roles', () => {
      const moduleInfos: IHubModule[] = [
        {
          name: ModuleNameTest.TEST as any,
          isEnabled: true,
          actions: {
            get: [BaseRole.STUDENT, BaseRole.EMPLOYEE],
            post: [BaseRole.ADMIN, BaseRole.UNVERIFIED_GUEST],
            update: [],
            del: [BaseRole.ADMIN, BaseRole.UNVERIFIED_GUEST, BaseRole.STUDENT],
          },
        },
      ];

      jest
        .spyOn(hubService, 'getModules')
        .mockImplementation(() => moduleInfos);

      const results: IHubModule[] = [
        {
          name: ModuleNameTest.TEST as any,
          isEnabled: true,
          actions: {
            post: [BaseRole.ADMIN, BaseRole.UNVERIFIED_GUEST],
            del: [BaseRole.ADMIN, BaseRole.UNVERIFIED_GUEST, BaseRole.STUDENT],
          },
        },
         {
          name: ModuleNameTest.TEST as any,
          isEnabled: true,
          actions: {
            get: [BaseRole.STUDENT, BaseRole.EMPLOYEE],
            del: [BaseRole.ADMIN, BaseRole.UNVERIFIED_GUEST, BaseRole.STUDENT],
          },
        },
       ]

      expect(
        hubService.getAvailableModulesAndActionsWithRoles([
          BaseRole.ADMIN,
          BaseRole.STUDENT,
        ]),
      ).toStrictEqual(results);
    });

This only work for one argument and I would like to get all module with available action for a given role. Is there a way to skip the action key instead of deleting it if the role is not found ? Because I needed on the next iteration.

CodePudding user response:

I think that instead of modifying the original modules, you should create copies with the required content.

getAvailableModulesAndActionsWithRoles(roles: string[]): IHubModule[] {
    const activeModules = this.getModules().filter(module => module.isEnabled);
    // selecting modules corresponding to each action
    return roles.flatMap(role => activeModules.map(
        module => {
            const actions = {};
            Object.keys(module.actions)
                .filter(key => Array.isArray(module.actions[key]) && module.actions[key].includes(role))
                .forEach(key => {
                    actions[key] = module.actions[key];
                });
            return {...module, actions } as IHubModule; 
        }
    ));
    //TODO We should also filter modules having empty actions
 }
  • Related