Слияние двух массивов из связанных запросов axios - PullRequest
0 голосов
/ 18 февраля 2019

Я связываю кучу аксиосов для получения запроса к различным конечным точкам API, и я пытаюсь создать подобный массив из данных (упрощенно):

[
    {
        name: "John",
        id: 1,
        gender: "male"
    },
    {
        name: "Anna",
        id: 2,
        gender: "female"
    },
]

В одном из запросовЯ извлекаю имя и идентификатор каждого человека из массива следующим образом:

[
    {
        name: "John",
        id: 1
    },
    {
        name: "Anna",
        id: 2
    },
]

Теперь мне нужно только определить их пол, посылая идентификатор каждого человека в двух отдельных запросах к конечной точке.

Iпотратили часы, пытаясь построить массив сверху с помощью push () и затем (), но я просто не могу понять это правильно.

Как мне это сделать?

Я создаю цепочку запросов axios следующим образом:

axios.get('api/' + endpoint1]).then(response => {
    axios.get('api/' + endpoint2).then(response => {
        axios.get('api/' + endpoint3).then(response => {
            // and so on...
         });
    });
});

ОБНОВЛЕНИЕ 1:

Мне кажется, что я не объяснил проблему должным образом,Вот так выглядит мой код прямо сейчас, начиная с последнего обещания.Как я могу изменить его, чтобы получить массив в верхней части моего вопроса?

.then(response => {

    people= response.data; // Array of people including their name id (not their gender though)

    for (var key in people) {

        var person = {};

        person["name"] = people[key].node.name;

        person["id"] = people[key].node.id;

        finalArray.push(person);

        axios.get('api/' + endpoint3, { // Endpoint for getting a persons gender from id
            params: {
                personId: person.id
                }
        }).then(response => {

            // I don't know what to do here...            

        });

    }

    console.log(finalArray); // Gives me an array of objects without "gender".

});

ОБНОВЛЕНИЕ 2:

Большое спасибо за ваши ответы!

Я объединил некоторые из ваших решений, и вот как сейчас выглядит мой реальный код.Запросы на http://api.ntjp.se/coop/api/v1/serviceProducers.json не отправляются. Почему?

Я также не хочу сохранять целые объекты в массиве ответов сотрудничества перед вызовом http://api.ntjp.se/coop/api/v1/serviceProducers.json. Я просто хочу сохранить две конкретные пары ключ / значение изкаждый объект.Эти две пары ключ / значение находятся внутри объекта с именем «serviceContract» внутри каждого объекта ответа. Как их сохранить?

<html>

<head>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>

<body>

    <script>

        getConnectionStatusData();

        async function getConnectionStatusData() {

            let serviceDomains = await axios.get('http://api.ntjp.se/coop/api/v1/serviceDomains.json', {
                                        params: {
                                            namespace: "crm:scheduling"
                                        }
                                    });

            serviceDomainId = serviceDomains.data[0].id;

            let connectionPoints = await axios.get('http://api.ntjp.se/coop/api/v1/connectionPoints.json', {
                                        params: {
                                            platform: "NTJP",
                                            environment: "PROD"
                                        }
                                    });

            connectionPointId = connectionPoints.data[0].id;

            let logicalAddresss = await axios.get('http://api.ntjp.se/coop/api/v1/logicalAddresss.json', {
                                        params: {
                                            logicalAdress: "SE2321000016-167N",
                                            serviceConsumerHSAId: "SE2321000016-92V4",
                                            connectionPointId: connectionPointId
                                        }
                                    });

            logicalAddressId = logicalAddresss.data[0].id;

            let serviceConsumers = await axios.get('http://api.ntjp.se/coop/api/v1/serviceConsumers.json', {
                                        params: {
                                            connectionPointId: connectionPointId,
                                            logicalAddressId: logicalAddressId
                                        }
                                    });

            consumer = serviceConsumers.data.filter(obj => {
                  return obj.hsaId === "SE2321000016-92V4"
                });

            serviceConsumerId = consumer[0].id;

            let cooperations = await axios.get('http://api.ntjp.se/coop/api/v1/cooperations.json', {
                                        params: {
                                            connectionPointId: connectionPointId,
                                            logicalAddressId: logicalAddressId,
                                            serviceDomainId: serviceDomainId,
                                            serviceConsumerId: serviceConsumerId,
                                            include: "serviceContract"
                                        }
                                    });

            for(var idx in cooperations.data) {

                var data = async () => { return await axios.get('http://api.ntjp.se/coop/api/v1/serviceProducers.json', {
                                        params: {
                                            connectionPointId: connectionPointId,
                                            logicalAddressId: logicalAddressId,
                                            serviceDomainId: serviceDomainId,
                                            serviceConsumerId: serviceConsumerId,
                                            serviceContractId: cooperations.data[idx].serviceContract.id
                                        }
                                    }) }
                cooperations.data[idx].producerDescription = data.description;
                cooperations.data[idx].producerHSAId = data.hsaId;
            }

            console.log(cooperations.data);

        }

    </script>

</body>

ОБНОВЛЕНИЕ 3

Я наконец заставил это работать, но почему ядолжны ссылаться на данные, такие как response.data[0].description, когда я в конце толкаю их в finalResult?Я имею в виду, почему не работает response.data.description, как для @Cold Cerberus?

Кроме этого, мой код в порядке или я что-то не так сделал?

Спасиборебята!

<html>

<head>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>

<body>

    <script>

        getConnectionStatusData();

        async function getConnectionStatusData() {

            let serviceDomains = await axios.get('http://api.ntjp.se/coop/api/v1/serviceDomains.json', {
                                        params: {
                                            namespace: "crm:scheduling"
                                        }
                                    });

            serviceDomainId = serviceDomains.data[0].id;

            let connectionPoints = await axios.get('http://api.ntjp.se/coop/api/v1/connectionPoints.json', {
                                        params: {
                                            platform: "NTJP",
                                            environment: "PROD"
                                        }
                                    });

            connectionPointId = connectionPoints.data[0].id;

            let logicalAddresss = await axios.get('http://api.ntjp.se/coop/api/v1/logicalAddresss.json', {
                                        params: {
                                            logicalAdress: "SE2321000016-167N",
                                            serviceConsumerHSAId: "SE2321000016-92V4",
                                            connectionPointId: connectionPointId
                                        }
                                    });

            logicalAddressId = logicalAddresss.data[0].id;

            let serviceConsumers = await axios.get('http://api.ntjp.se/coop/api/v1/serviceConsumers.json', {
                                        params: {
                                            connectionPointId: connectionPointId,
                                            logicalAddressId: logicalAddressId
                                        }
                                    });

            consumer = serviceConsumers.data.filter(obj => {
                  return obj.hsaId === "SE2321000016-92V4"
                });

            serviceConsumerId = consumer[0].id;

            let cooperations = await axios.get('http://api.ntjp.se/coop/api/v1/cooperations.json', {
                                        params: {
                                            connectionPointId: connectionPointId,
                                            logicalAddressId: logicalAddressId,
                                            serviceDomainId: serviceDomainId,
                                            serviceConsumerId: serviceConsumerId,
                                            include: "serviceContract"
                                        }
                                    });

            var finalData = [];

            cooperations.data.forEach(function(cooperation) {

                axios.get('http://api.ntjp.se/coop/api/v1/serviceProducers.json', {
                            params: {
                                connectionPointId: connectionPointId,
                                logicalAddressId: logicalAddressId,
                                serviceDomainId: serviceDomainId,
                                serviceConsumerId: serviceConsumerId,
                                serviceContractId: cooperation.serviceContract.id
                            }
                }).then(response => {
                finalData.push({serviceContract: cooperation.serviceContract.namespace, serviceProducerDescription: response.data[0].description, serviceProducerHSAId: response.data[0].hsaId});
            });


            });

            console.log(finalData);



        }

    </script>

</body>

Ответы [ 3 ]

0 голосов
/ 18 февраля 2019

Я не люблю читать цепочечные обещания и предпочитаю использовать async/await.Вы могли бы сначала получить свой список, а затем просмотреть этот список с помощью map и запросить пол для каждого имени.Помните, что вам нужно дождаться выполнения всех обещаний внутри вашего map, прежде чем вы сможете продолжить.

const axios = require('axios');

async function getPeople() {
    let firstResult = await axios.get('api/path/endpoint1');
    // firstResult = [{name: "John", id: 1}, {name: "Anna", id: 2}]

    let updatedResult = firstResult.map(async item => {
        let people = await axios.get('api/path/endpoint2' + item.name); // or however your endpoint is designed 
        // people = {name: "John", id: 1, gender: male}
        item.gender = people.gender;
        return item; 
    });
    // updatedResult = undefined

    Promise.all(updatedResult)
        .then(finalResult => console.log(finalResult));
    //  [{name: "John", id: 1, gender: male}, {name: "Anna", id: 2, gender: female}]
}
0 голосов
/ 18 февраля 2019

Вы можете использовать async / awaits и переназначить ключ gender для данных первой конечной точки ...

var users;
axios.get('api/' + endpoint1]).then(response => {
   users = response; // assume all user id list
   for(var idx in users) {
     var data = async () => { return await axios.get('api/' + users[idx].id) } //get gender api by user id
     users[idx].gender = data.gender; //create gender key value 
   }
   console.log(users);
});
0 голосов
/ 18 февраля 2019

Я не совсем уверен в вашей конкретной проблеме.Но при условии, что вы имеете в виду, что у вас есть две конечные точки, первая - это та, которая возвращает массив объектов (назовем его 'getPeopleArray'):

[
 {
    name: "John",
    id: 1
 },
 {
    name: "Anna",
    id: 2
 }
]

, а вторая конечная точка возвращает genderучитывая id (давайте назовем его 'getGender' с одним параметром id), .push не выполнит работу за вас.

Ваша проблема может быть решена с помощью чего-то подобного:

let peopleArray = [];
axios.get('api/' + 'getPeopleArray').then(people => {
    peopleArray = people;
    people.forEach((person, index) => {
       axios.get('api/' + 'getGender?id='.concat(person.id.toString()))
           .then(gender => {
               peopleArray[index].gender = gender;
           });
    });
});

Сначала вы сохраняете возвращенный массив вашего первого запроса, а затем вам придется циклически проходить через каждый объект в этом массиве, чтобы получить и назначить их genders из вашей второй конечной точки, используя аргумент index вашего [].forEach(callbackfn).Пока нет никаких манипуляций с peopleArray во время или до завершения всех запросов, индекс будет правильным.

Обновление 2: В ответ на ваш вопрос в комментариях "почему.push не работает? ", я решил использовать другой подход. Если вы хотите завершить свой алгоритм с помощью .push и обойтись без отслеживания индексов.

let peopleArray = [];
axios.get('api/' + 'getPeopleArray').then(people => {
    people.forEach((person) => {
       axios.get('api/' + 'getGender?id='.concat(person.id.toString()))
           .then(gender => {
               peopleArray.push({id: person.id, name: person.name, gender, gender});
           });
    });
});

Таким образом, вы будете только толкать свой объектв вашу коллекцию peopleArray, когда выбран соответствующий пол.Это также избавит от необходимости использовать .map (как предлагается в комментариях) для хранения только тех свойств отдельного объекта, которые вы хотите сохранить, поскольку вы поместили новый структурированный объект в строку peopleArray.push({id: person.id, name: person.name, gender, gender});.

...