Search code examples
javascriptsails.js

How to property create and reference dynamic variable names in script


I have a piece of code which works manually, but I am trying to make more reusable for growth. In the function's current state, it sets a large list of manually created arrays. Then does a DB call for weekly snapshot numbers, and runs them through a foreach sort with a switch/case which pushes those values into the correct array. During that process it also puts together a list of all the workweeks recorded, then removes duplicates, transforms those workweeks into a string and pushes them to their own array. Then it runs queries for live data, and pushes the results to the existing arrays. After that it returns the built object.

The code looks like this:

globalCap: async function (req, res) {
        try {
            let af = [], workweeks = [], bf = [], ca = [], da = [], fr = [], gl = [], ch = [];
            let snapshots = await Snapshot.find().sort('createdTS ASC');
            snapshots.forEach(element => {
                switch (element.parentLocation) {
                    case 'AF':
                        af.push(element.totalSpaces);
                        break;
                    case 'BF':
                        bf.push(element.totalSpaces);
                        break;
                    case 'CA':
                        ca.push(element.totalSpaces);
                        break;
                    case 'DA':
                        da.push(element.totalSpaces);
                        break;
                    case 'FR':
                        fr.push(element.totalSpaces);
                        break;
                    case 'CH':
                        ch.push(element.totalSpaces);
                        break;
                    default:
                        break;
                }
                workweeks.push(element.workweek);
            });

            let uniqueWW = [...new Set(workweeks)];
            uniqueWW.forEach(element => {
                i = 'WW' + element;
                gl.push(i);
            });

            let afLive = await Location.count({
                parentLocationID: 1
            });
            af.push(afLive);
            let bfLive = await Location.count({
                parentLocationID: 2
            });
            bf.push(bfLive);
            let caLive = await Location.count({
                parentLocationID: 3
            });
            ca.push(caLive);
            let daLive = await Location.count({
                parentLocationID: 4
            });
            da.push(daLive);
            let frLive = await Location.count({
                parentLocationID: 5
            });
            fr.push(frLive);
            let chLive = await Location.count({
                parentLocationID: 6
            });
            ch.push(chLive);
            ww = 'WW' + workweek();
            gl.push(ww);
            return res.ok({
                'AF': af,
                'BF': bf,
                'CA': ca,
                'DA': da,
                'FR': fr,
                'CH': ch,
                'ww': gl,
            });
        }
        catch (error) {
            console.error(error);
        }
    },

And outputs this for use on some charts on the frontend:

    {
        "AF": [80,80,80],
        "BF": [131,131,131],
        "CA": [0,0,0],
        "DA": [78,78,78],
        "FR": [0,0,0],
        "CH": [0,171,171],
        "ww": ["WW1","WW2","WW3"]
      }

However, as this grows, I'd like to have the arrays created dynamically, based off the results of a query.

So I added a siteInfo query to the start which pulls and maps into the 2 componants I need, campusCode and id:

    const siteInfo = await ParentLocation.find();
    const sites = siteInfo.map(obj => ({
        campusCode: obj.campusCode,
        id: obj.id
    }));

Which gives this output:

  [
    { campusCode: 'AF', id: 1 },
    { campusCode: 'BF', id: 2 },
    { campusCode: 'CA', id: 3 },
    { campusCode: 'DA', id: 4 },
    { campusCode: 'FR', id: 5 },
    { campusCode: 'CH', id: 6 }
  ]

What would be the best way to sort and push the snapshot data into arrays, then reference them again to push the "live" data onto the end of each array based on the parentLocationID query? I feel like there is an easier way to do this, but I'm getting further and further into the weeds on it.


Solution

  • The answers I got here were helpful, thank you! After restructuring some things, I'm now able to build the object reliably, not matter how many results are returned in the initial query. Here is the final code I ended up going with:

       globalCap2: async function (req, res) {
            try {
                let gl = [], workweeks = [], campusSpaces = {};
                const siteInfo = await ParentLocation.find();
                const sites = siteInfo.map(obj => ({
                    campusCode: obj.campusCode,
                    id: obj.id
                }));
    
                sites.forEach(element => {
                    const campusCode = element.campusCode;
                    campusSpaces[campusCode] = {};
                    campusSpaces[campusCode].id = element.id;
                    campusSpaces[campusCode].trend = [];
                });
    
                let snapshots = await Snapshot.find().sort('createdTS ASC');
                snapshots.forEach(element => {
                    const campusCode = element.parentLocation;
                    if (campusSpaces[campusCode]) {
                        campusSpaces[campusCode].trend.push(element.totalSpaces);
                    }
                    workweeks.push(element.workweek);
                });
    
                for (let key in campusSpaces) {
                    id = campusSpaces[key].id
                    let live = await Location.count({
                        parentLocationID: id
                    });
                    campusSpaces[key].trend.push(live);
                }
    
                let uniqueWW = [...new Set(workweeks)];
                uniqueWW.forEach(element => {
                    i = 'WW' + element;
                    gl.push(i);
                });
                ww = 'WW' + workweek();
                gl.push(ww);
                campusSpaces.WW = gl;
    
                return res.ok(campusSpaces);
            }
            catch (error) {
                console.error(error);
            }
        },