0

Without going too much in the details, my question is, how would you go about reducing the repetition in NodeJS? I am very much a beginner so please have mercy.

I am getting an api with the information, and output my own api which is that information filtered and sorted according to the req.query parameters (from, to, date).

This is the code that works, but has too much repetition in it:

app.get('/search', async (req, res, next) => {
try {
    const apiRes = await axios.get('https://thistheapi.net/api/TravelPrices');
    result = apiRes.data;
    searchFrom = req.query.from;
    searchTo = req.query.to;
    searchDate = req.query.date;
    const routesArray = [];
    for (let route of result) { routesArray.push(route) };

    if (searchFrom.toLowerCase() == "mercury" && searchTo.toLowerCase() == "earth") {

        finalResult = [];

        // Finding and filtering the first flight

        const fromFilterF1 = "Mercury";

        // Create an array, which has the results of routes that match the req.query from name/ aka starting point

        firstArrayF1 = routesArray.filter(obj => obj.routeInfo.from.name == fromFilterF1);
        const toFilterF1 = "Venus";

        // Filter the resulting array with the next 'to' location

        secondArrayF1 = firstArrayF1.filter(obj => obj.routeInfo.to.name == toFilterF1);

        // Create an array that has all the providers with their data for this specific route / flight
        const providerArrayF1 = secondArrayF1.map(x => x.providers)
        const trialArrayF1 = [];
        
        for (let x of providerArrayF1) { for (let y of x) { trialArrayF1.push(y) } }

        // Use the req.query selected date to filter all flights that match the date

        dateFilterF1 = { flightStart: searchDate };

        // options for the date variable, since in the api data it has specific time of day also added

        const options = { year: 'numeric', month: 'numeric', day: 'numeric' };
        thirdArrayF1 = trialArrayF1.filter(obj => new Date(obj.flightStart).toLocaleDateString('en-CA', options) == dateFilterF1.flightStart);

        // Sort the resulting array of matching from-location, to-location, and date - starting from the earliest flights to the latest one

        thirdArrayF1.sort((a, b) => { return new Date(a.flightStart) - new Date(b.flightStart) });

        finalResult.push(thirdArrayF1[0]);

        // ALL OF THIS REPEATS FOR THE SECOND & THIRD FLIGHT, except the flight start date/time has to be later than the flight end time of the previous flight

        // Finding and filtering the second flight
        if (thirdArrayF1.length == 0) { finalResult.push(null) } else {
            const fromFilterF2 = "Venus";
            firstArrayF2 = routesArray.filter(obj => obj.routeInfo.from.name == fromFilterF2);
            const toFilterF2 = "Earth";
            secondArrayF2 = firstArrayF2.filter(obj => obj.routeInfo.to.name == toFilterF2);
            const providerArrayF2 = secondArrayF2.map(x => x.providers)
            const trialArrayF2 = [];
            for (let x of providerArrayF2) { for (let y of x) { trialArrayf2.push(y) } }
            dateFilterF2 = { flightStart: thirdArrayF1[0].flightEnd };
            thirdArrayF2 = trialArrayF2.filter(obj => new Date(obj.flightStart).toLocaleDateString('en-CA', options) >= dateFilterF2.flightStart);
            thirdArrayF2.sort((a, b) => { return new Date(a.flightStart) - new Date(b.flightStart) });
            finalResult.push(thirdArrayF2[0])
        };
            // Finding and filtering the third flight
            if (thirdArrayF2.length == 0) { finalResult.push(null) } else {
                const fromFilterF3 = "Earth";
                firstArrayF3 = routesArray.filter(obj => obj.routeInfo.from.name == fromFilterF3);
                const toFilterF3 = "Jupiter";
                secondArrayF3 = firstArrayF3.filter(obj => obj.routeInfo.to.name == toFilterF3);
                const providerArrayF3 = secondArrayF3.map(x => x.providers)
                const trialArrayF3 = [];
                for (let x of providerArrayF3) { for (let y of x) { trialArrayF3.push(y) } }
                dateFilterF3 = { flightStart: thirdArrayF2[0].flightEnd };
                thirdArrayF3 = trialArrayF3.filter(obj => new Date(obj.flightStart).toLocaleDateString('en-CA', options) >= dateFilterF3.flightStart);
                thirdArrayF3.sort((a, b) => { return new Date(a.flightStart) - new Date(b.flightStart) });
                finalResult.push(thirdArrayF3[0])
            };
        res.json(finalResult);

        } else if (searchFrom.toLowerCase() == "mercury" && searchTo.toLowerCase() == "jupiter"){ etc...

As you can see, there is a lot of similar code, but I can't figure out how to make it more compact and less repetitive, without breaking the code and it stopping to work.

I appreciate all the help and advice!

Also, this is a snippet of the api that I use:

"legs":[{"id":"a0ee2c2b-667c-46d7-87c0-2ca32da88a46","routeInfo":{"id":"44edd88d-8904-4266-9df5-f37701741123","from":{"id":"0ee3379b-98fb-4b46-9aef-0a3a81a46ad4","name":"Earth"},"to":{"id":"a504bf72-2be2-4f2b-bab1-61d818757e3a","name":"Jupiter"},"distance":628730000},"providers":[{"id":"0257eab0-7c5c-4a4c-af79-cdf6f3ab9349","company":{"id":"27b1ce2f-c88a-45f4-96e1-dd9fcbb2db73","name":"Spacegenix"},"price":570774.60,"flightStart":"2022-02-04T07:17:16.4529653Z","flightEnd":"2022-02-08T13:57:16.4529653Z"},{"id":"e6ed4071-e29c-46a1-a38f-a082eff0e4de","company":{"id":"eb12838f-afb4-4447-9781-2d87b0641337","name":"Galaxy Express"},"price":180679.62,"flightStart":"2022-02-13T00:30:16.4529883Z","flightEnd":"2022-02-17T14:29:16.4529883Z"} et cetera.

Basically I'm doing custom connected flights between different locations. I am sure there is a way to make this less repetitive, but I can't figure it out.

Henry
  • 21
  • 4
  • It looks like you're already familiar with functions, objects, arrays and loops. Create a parametrizable function and call it in a loop, and store the data in an array/object instead of indexed variables. Every time you find yourself creating indexed variables, you know something is going wrong. – Teemu Feb 02 '22 at 12:24
  • My first idea was also to make a function that takes three parameters, and then repeats with the resulting array, but I didn't get it to work. I'll continue going that path and trying again. Indexed variables means its already too much, got it. Thank you! – Henry Feb 02 '22 at 12:53

0 Answers0