1

Is there any way I can make the below code run synchronously in a way where I can get all of the productLine ids and then loop through and delete all of them, then once all of this is complete, get all of the productIds and then loop through and delete all of them?

I really want to be able to delete each set of items in batch, but the next section can't run until the first section is complete or there will be referential integrity issues.

// Delete Product Lines
axios.get('https://myapi.com/ProductLine?select=id')
    .then(function (response) {
        const ids = response.data.value

        ids.forEach(id => {
            axios.delete('https://myapi.com/ProductLine/' + id)
        })
    })
    .catch(function (error) {

    })

// Delete Products (I want to ensure this runs after the above code)
axios.get('https://myapi.com/Product?select=id')
    .then(function (response) {
        const ids = response.data.value

        ids.forEach(id => {
            axios.delete('https://myapi.com/Product/' + id)
        })
    })
    .catch(function (error) {

    })

3 Answers 3

1

There's a lot of duplication in your code. To reduce code duplication, you can create a helper function that can be called with appropriate arguments and this helper function will contain code to delete product lines and products.

async function deleteHelper(getURL, deleteURL) {
   const response = await axios.get(getURL);
   const ids = response.data.value;

   return Promise.all(ids.map(id => (
      axios.delete(deleteURL + id)
   )));
}

With this helper function, now your code will be simplified and will be without code duplication.

Now to achieve the desired result, you could use one of the following ways:

  • Instead of two separate promise chains, use only one promise chain that deletes product lines and then deletes products.

    const prodLineGetURL = 'https://myapi.com/ProductLine?select=id';
    const prodLineDeleteURL = 'https://myapi.com/ProductLine/';
    
    deleteHelper(prodLineGetURL, prodLineDeleteURL)
      .then(function() {
         const prodGetURL = 'https://myapi.com/Product?select=id';
         const prodDeleteURL = 'https://myapi.com/Product/';
         deleteHelper(prodGetURL, prodDeleteURL);
      })
      .catch(function (error) {
          // handle error
      });
    
  • Use async-await syntax.

    async function delete() {
       try {
         const urls = [
            [ prodLineGetURL, prodLineDeleteURL ],
            [ prodGetURL, prodDeleteURL ]
         ];
    
         for (const [getURL, deleteURL] of urls) {
            await deleteHelper(getURL, deleteURL); 
         }
    
       } catch (error) {
         // handle error
       }
    }
    

One other thing that you could improve in your code is to use Promise.all instead of forEach() method to make delete requests, above code uses Promise.all inside deleteHelper function.

Sign up to request clarification or add additional context in comments.

12 Comments

thank you so much! I am creating a CLI using node.js that makes a bunch of web api calls. Will I be able to use async-await since it is not part of CommonJS?
Yes you can use async-await syntax in nodejs. CommonJS is a module system, it has nothing to do with async-await syntax.
sorry about that, I know I was reading somewhere that async-await doesn't work in certain browsers or something like that. I am assuming I don't need to worry for a cli.
Support for async-await syntax is pretty good at this point but as your code won't be running in the browsers, you don't need to worry about it.
Quick question, in the deleteHelper I am doing the following: const ids = response.data.value.map(idObj => idObj.id) which is slightly different than your example. I need to call map since response.data.value is an array of objects such as [{"id": "1000"}, {"id": "2000"}, {"id": "2000"}]. Do I need to call await on this? The reason I ask is because I am still getting referencial integrity errors when trying to delete the Products as if all the ProductLine deletes didn't complete first. Is that even possible?
|
1

Your code (and all other answers) are executing delete requests sequentially, which is huge waste of time. You should use Promise.all() and execute in parallel...

// Delete Product Lines
axios.get('https://myapi.com/ProductLine?select=id')
    .then(function (response) {
        const ids = response.data.value

        // execute all delete requests in parallel
        Promise.all(
          ids.map(id => axios.delete('https://myapi.com/ProductLine/' + id))
        ).then(
          // all delete request are finished
        );        
    })
    .catch(function (error) {

    })

Comments

0

All HTTP request are asynchronous but you can make it sync-like. How? Using async-await

Suppose you have a function called retrieveProducts, you need to make that function async and then await for the response to keep processing.

Leaving it to:

const retrieveProducts = async () => {

// Delete Product Lines
const response = await axios.get('https://myapi.com/ProductLine?select=id')
const ids = response.data.value
ids.forEach(id => {
  axios.delete('https://myapi.com/ProductLine/' + id)
})

// Delete Products (I want to ensure this runs after the above code)
const otherResponse = await axios.get('https://myapi.com/Product?select=id') // use proper var name
const otherIds = response.data.value //same here
otherIds.forEach(id => {
  axios.delete('https://myapi.com/Product/' + id)
})
}

But just keep in mind that it's not synchronous, it keeps being async

1 Comment

Not a good solutioon. All delete requests are executed sequentially

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.