10

I have an API that returns a list of replies (limit 5 replies per call) for a message board thread. What I am trying to do, is look for a specific reply uuid in the response. If not found, make another AXIOS GET call for the next 5 replies.

I want to continue this loop until the UUID is called or the AXIOS GET call comes back with no results.

Example API Request:

http://localhost:8080/api/v2/replies?type=thread&key=e96c7431-a001-4cf2-9998-4e177cde0ec3

Example API Reponse:

"status": "success",
"data": [
    {
        "uuid": "0a6bc471-b12e-45fc-bc4b-323914b99cfa",
        "body": "This is a test 16.",
        "created_at": "2017-07-16T23:44:21+00:00"
    },
    {
        "uuid": "0a2d2061-0642-47eb-a0f2-ca6ce5e2ea03",
        "body": "This is a test 15.",
        "created_at": "2017-07-16T23:44:16+00:00"
    },
    {
        "uuid": "32eaa855-18b1-487c-b1e7-52965d59196b",
        "body": "This is a test 14.",
        "created_at": "2017-07-16T23:44:12+00:00"
    },
    {
        "uuid": "3476bc69-3078-4693-9681-08dcf46ca438",
        "body": "This is a test 13.",
        "created_at": "2017-07-16T23:43:26+00:00"
    },
    {
        "uuid": "a3175007-4be0-47d3-87d0-ecead1b65e3a",
        "body": "This is a test 12.",
        "created_at": "2017-07-16T23:43:21+00:00"
    }
],
"meta": {
    "limit": 5,
    "offset": 0,
    "next_offset": 5,
    "previous_offset": null,
    "next_page": "http://localhost:8080/api/v2/replies?_limit=5&_offset=5",
    "previous_page": null
}

The loop would call an AXIOS GET on the meta > next_page url until either the uuid is found in the results or the meta > next_page is null (meaning no more replies).

ATLChris
  • 3,198
  • 7
  • 39
  • 65
  • What have you tried? So far it looks like you haven't made an effort. – David L Jul 19 '17 at 02:28
  • Some context? Is this in a Vue method? – Bert Jul 19 '17 at 02:33
  • @DavidL I have been playing with it for a while. I have tried traditional `while` loops, which don't work because of the AXIOS promise. I have also tried building a promise while loop (https://gist.github.com/tangzhen/7b9434df8beac308fd3e), but that wouldn't work either. – ATLChris Jul 19 '17 at 02:37
  • @BertEvans It is inside the "created" hook of a Vue.js 2 component. – ATLChris Jul 19 '17 at 02:39
  • check this out, [while loop w/ promises](https://stackoverflow.com/questions/17217736/while-loop-with-promises) – aarosil Jul 19 '17 at 02:43

2 Answers2

8

What you should search for is not while loop, but it's called Recursion:

while:

var counter = 10;
while(counter > 0) {
    console.log(counter--);
}

recursion:

var countdown = function(value) {
    if (value > 0) {
        console.log(value);
        return countdown(value - 1);
    } else {
        return value;
    }
};
countdown(10);

It means that the function keeps calling itself based on specific criteria on the output. This way you can create a function that handles the response and call itself again if the value doesn't suit you well (semicode):

function get() {
    axios.get('url').then(function(response) {
        if (response.does.not.fit.yours.needs) {
            get();
        } else {
            // all done, ready to go!
        }
    });
}

get();

If you want it chained with promises then you should spend some time figuring it out by yourself, just returning a promises each time ;)

Andrey Popov
  • 7,362
  • 4
  • 38
  • 58
  • Wouldn't this cause a stack overflow eventually? – Novaterata Jan 08 '19 at 22:16
  • 1
    That's why it always has an `if` condition, so it will call the same function again `only` if the requirement is met. In the first case it's `if (value > 0)`, and in the second - `if (response.does.not.fit.your.needs)`, which basically is whatever you like :) – Andrey Popov Jan 09 '19 at 11:52
  • Oh sorry, didn't see that, I was focused on MY particular while condition which is not counter based but based on the status of a long running job. In that case it could still cause a stack overflow. I didn't even think of the counter, because I don't know why anyone would use a while loop for a counter instead of for. I ended up using setInterval and clearIntetval because I couldn't find a recursive solution that addressed this concern. I still think this should be addressed in the answer considering the _title_ of the question – Novaterata Jan 09 '19 at 15:15
  • I think I've answered user's question in a proper way, working with his explanation as well as his own example. So both cases (with or without while) are included. Feel free to use any of them ;) Not entirely sure why the answer does not satisfy your needs – Andrey Popov Jan 09 '19 at 16:01
  • A while condition could be non-deterministic and run forever or enough to times to cause a stack overflow with recursion. "How can I "while loop" an Axios GET call till a condition is met?" That is the title, not "How can I "while loop" an Axios GET call till a deterministic counter condition is met?" – Novaterata Jan 09 '19 at 16:08
  • 1
    I don't seem to understand what you're actually bragging about :) If you're still looking to work with axios responses in a while loop, then I think we should end this discussion straight away ;) If you have a better answer, please post it. These kind of talks don't help anyone, but even make people more confused. – Andrey Popov Jan 09 '19 at 17:12
7

This is trivial if you you are precompiling with something that supports async/await. Below is just an example. In your case you would be checking for your guid or an empty response.

new Vue({
  el:"#app",
  methods:{
    async getStuff(){
      let count = 0;
      while (count < 5){
        let data = await axios.get("https://httpbin.org/get")
        console.log(data)
        count++
      }
    }
  },
  mounted(){
    this.getStuff()
  }
})

Or, per your response to my comment,

new Vue({
  el:"#app",
  async created(){
      let count = 0;
      while (count < 5){
        let data = await axios.get("https://httpbin.org/get")
        // check here for your guid/empty response
        console.log(data)
        count++
      }
  }
})

Working example (in latest Chrome at least).

Bert
  • 80,741
  • 17
  • 199
  • 164
  • You should not use `async` and `await` in browsers yet, as they make tons of blown up code, and are still slow :) – Andrey Popov Jul 19 '17 at 10:20
  • @AndreyPopov I mention in the first line about precompiling. – Bert Jul 19 '17 at 10:22
  • I see you've mentioned precompiling, but it's still not good for web browsers (unfortunately!) :( – Andrey Popov Jul 19 '17 at 10:26
  • @AndreyPopov will agree to disagree. Any performance issue would be overwhelmed by the fact it's making a network call and simple clarity. – Bert Jul 19 '17 at 10:29