Array logic match for list

Asked by At

I have a quick links widget with different types of links/menus that the user can choose from. Only four different menu options can be shown at the same time - not more or less.

In code I first extract all the menu options which come in the form in [1,2,3...] which corresponds to the rows in a list where the menu options is stored.

The user chooses menu options is also returned in the same way with an array like [2,3,8,9] with the number corresponding which row to get from the list.

Example:

All menu/widgets

  1. Travel
  2. Hotel
  3. Car
  4. Buss
  5. Airplane
  6. Holiday

This will return an array [1,2,3,4,5,6]

And if I choose to save hotel, buss, airplane and holiday then my user settings will return [2,4,5,6].

Problem: It works, until a widget is deleted from the list that the user has saved then the widget only will show three menus/links. I want the widget to always show four links, so if one is missing I need to populate the array. So if its missing, I want to show another link. It would be good, but not needed, to take a link that is set to default when its missing (always the first four in the list). I have set up a logic for that but its not working.

Code:

public async getUserWidgets(): Promise<Widget[]> {
    return new Promise<Widget[]>(async(resolve, error) => {
    let allWidgets = await this.getAllWidgets(); // Returns an array of all links [1,2,4...]

    let userRepository = new UserProfileRepository(this.absoluteWebUrl);
    let userSettings = await userRepository.getUserExtensionValues(this.context); //contains the user saved widgets ex [2,3,6,7]

    var result:Widget[] = [];

// if the user has no settings, or less than 4 saved links

    if (userSettings == null || userSettings.QuickLinksWidgets == null || userSettings.QuickLinksWidgets.length <  4) {
        result = allWidgets.filter((w) => {return w.defaultWidget;}).slice(0,4);   //default widget but not really needed.
    }
    else {
        var ids = userSettings.QuickLinksWidgets;

        for (let i = 0; i < 4; i++) {
            let id = '' + ids[i];
            let w = allWidgets.filter((e) => { return e.id == id;});

            if (w.length == 0) {
                continue;
            }

            result.push(w[0]);

        }

    };
    resolve(result);
      }); }

1 Answers

0
mguida On

From what you described, it sounds like maybe you're not updating properly (calling getUserWidgets when userSettings.QuickLinksWidgets changes? First check to make sure it's called as you expect.

If getUserWidgets is being called properly, try to add defaults to their settings until you have 4 links total. Right now you are using default links if they have any less than 4 in their settings.

For example:

// take up to 4 user links and make sure we don't exceed the length of the array
for (let i = 0; i < 4 && i < userSettings.QuickLinksWidgets.length - 1; i++) {
  // get the id of the widget in the user's settings
  let widgetId = userSettings.QuickLinksWidgets[i].id
  // find the widget with a matching id and add it to our results
  result.push(allWidgets.find(w => w.id === widgetId)
}

// if there's not already 4 links, add more to our list
let j = 0
while (result.length < 4) {
  // check the first 4 user links to make sure we didn't include this link already
  if (!userSettings.QuickLinksWidgets.slice(0, 4).includes(allWidgets[j].id)) {
    // add the new widget to the results
    result.push(allWidgets[j])
  }

  j++
}

resolve(result)