0
getUsers();

function getUsers(){
    console.log('Start');

    $.ajax({
        url: 'https://jsonplaceholder.typicode.com/users',
        method: 'GET',
        dataType: 'json',
        success: function (data) {
                data.forEach(user => {
                    console.log(user.id);
                 });                    
        },
        error: function () {
            console.log(data.status);
        }
        
    })

    console.log('End');    
}

The above code-example should print the following: Start ids ... End

However it has the following problem: The order of printing of the data is wrong. It prints Start End data-object

I know it has to do with async, however I can't fix the problem. I tryed alot of things like $.When() Promise async/await But none of them helped.

So could you please show how to fix this problem?

Thank you in advance

John
  • 35
  • 1
  • 7
  • 3
    As far as I can tell, data doesn't have a property success. So you're checking for something that isn't there (data.success) and so it goes to the other branch of the if. It works just fine with dataType: json, put console.log(data) before the if and you'll see the response, which has all the data you're expecting. – Chris Strickland Feb 15 '22 at 01:08
  • 2
    dataType should be one of the strings as specified in the documentation i.e xml, json, jsonp, html, script etc, nothing suggests you put a mime type in there ... the documentation does not state what happens if you use something else, I assume it uses the default "intelligent guess" logic – Bravo Feb 15 '22 at 01:08
  • 1
    `It prints Start End data-object` - because the first `a` in `ajax` stands for **asynchronous** - so, yeah, `end` is logged before the request completes - that's asynchrony – Bravo Feb 15 '22 at 01:13
  • Now I've corrected the code. Now it prints the data. As I mentioned in my post, I know that ajax is async and I've tried many solutions. but I can not get it fixed. – John Feb 15 '22 at 01:39
  • There are plenty of options listed in the post linked at the top of your question – Phil Feb 15 '22 at 01:45
  • As I wrote in my first post: I did try all of these options, but none of them helped. Certainly I misunderstand something. One thing, that I don't want to do is to set async to false. I want to do it asynchrounus. So the linked post does not help me unfortunately. – John Feb 15 '22 at 01:51
  • 1
    What did you try and how did it not work? Adding `.done(() => console.log("End"))` like in [this answer](https://stackoverflow.com/a/23283344/283366) would be what I would do but there are many other options – Phil Feb 15 '22 at 02:33
  • @Phil This works! Thank you indeed. I can't believe it. Because I had tried it with done() and then() and When() and Promise and really everything but it didn't work. The problem was: the whole time I wrote `.done(console.log('End'))` instead of `.done(() => console.log("End"))`. So that was the magic. And I spent some three days to figure out where the problem is. It was very frustrating. If you write it as an answer I'l mark it as the solution. So once again thank you for you great help. You saved me alot of time :-) – John Feb 15 '22 at 02:59
  • This question is already closed as a duplicate. Give your upvotes to the answers in the other post that helped. – Phil Feb 15 '22 at 03:09
  • Okay the other answer is upvoted. Have a nice day! – John Feb 15 '22 at 03:16

1 Answers1

0

Ajax is asynchronous, the successor the error function will be called later, when the server answer the client. That is why sometimes you can see data.status displayed before End in your last console.log statement. Second, data that you are getting from response does not contain field success. Success callback function gets passed three arguments: The data returned from the server, formatted according to the dataTypeparameter or the dataFilter callback function, if specified; a string describing the status; and the jqXHTobject. In your code you are just passing first argument to it which is data returned from server.

Nemanja
  • 3,295
  • 11
  • 15
  • Thanks for your response. As I wrote, I tried everything but I can't solve the problem. And now is my question marked as closed which I can't understand. So if you could show how to fix the problem it would be very helpful. – John Feb 15 '22 at 01:55
  • 1
    data doesn't have a success property. Or a results. either. Change the dataType back to json and make this your success function: `success: function (data) {data.forEach(user => {console.log(user.id)})}` and tell me if that doesn't do what you want. – Chris Strickland Feb 15 '22 at 02:07
  • @ChrisStrickland Thank you for your answer. This problem is solved and I've corrected the code s. above. The big problem ist the wrong order of the printing. As I said, I know that the problem has to do with async. But I'm not able to fix it. So If you have a solution for that, it would be great. Thanks again. – John Feb 15 '22 at 02:14
  • You can't guarantee the order of asynchronous events, by definition. You either change it to be synchronous, or you move the Start and End inside the success function. – Chris Strickland Feb 15 '22 at 02:57
  • @ChrisStrickland Now it works fine with `.done(() => console.log('End'))` or the other style `.done(function() {console.log('End')})` as by @Phil answered. Thank you for your help. – John Feb 15 '22 at 03:13