3

I am trying to make a chrome extension which fetches IDs of Youtube videos, but am facing a problem. For first execution, the AJAX call gives me an error, but for all subsequent calls, works just fine. This happens every time I open the extension. I am new to the scene, and hence, please excuse me for any rookie mistakes. My code :-

function getIDs(data){
    var items = [];
    for(i in data.items){
        items.push(data.items[i].id.videoId.toString());
    }
    for(i in items){
        $('<p>'+items[i]+'</p><br>').appendTo('#results');
    }
}

function getVideo(searchQuery){
    searchQuery = searchQuery.replace(/ /g,'+');
    var queryURL = 'https://www.googleapis.com/youtube/v3/search?q='+searchQuery+'&key=AIzaSyDq5SqWuQIEfIx7ZlQyKcQycF24D8mW798&part=snippet&maxResults=3&type=video';
    $.ajax({
        url: queryURL,
        dataType: 'json',
        success: function(data) {   
            getIDs(data);
        },
        error: function(ts){
            alert(ts.responseText);
        }
    });
}

document.addEventListener('DOMContentLoaded',function(){
    var button = document.getElementById('search');
    var div = document.getElementById('results');
    button.addEventListener('click',function(){
        var input = document.getElementById('input');
        var result = input.value;
        getVideo(result);
    });
});

I can't for the life of me figure out what is wrong. Thanks for the help in advance.

EDIT

I forgot to mention, but it gives me an undefined error. Sorry !!

  • 1
    What error is it giving you? – neilsimp1 May 27 '16 at 18:59
  • `ts.responseText` gives me undefined – Dhanvi Sreenivasan May 27 '16 at 19:00
  • 3
    Try adding `console.log(ts);` instead and check the console for the error – Alon Eitan May 27 '16 at 19:01
  • Do an add watch on `ts` . See what has returned – Akshay G May 27 '16 at 19:03
  • `Object {readyState: 0, responseJSON: undefined, status: 0, statusText: "error"}` This is what i got. Any clue?? BTW what is an add watch? – Dhanvi Sreenivasan May 27 '16 at 19:06
  • No idea, maybe try to change `DOMContentLoaded` to `load` - perhaps you are loading external JS libraries? Check the `network` tab in the developer tools - see if there is something different in the first request, maybe a new header is being added – Alon Eitan May 27 '16 at 19:20
  • @Alon, this removed the undefined error, but the div does not populate as it should. But, on subsequent calls, div populates just fine – Dhanvi Sreenivasan May 27 '16 at 19:33
  • Are there any messages in console about `XMLHttpRequest`? (or any errors at all?) – libcthorne May 27 '16 at 19:34
  • So add `console.log(data)` to see the data returned on the first time (Because _the div does not populate as it should_ is too broad definition for the problem you're having) – Alon Eitan May 27 '16 at 19:38
  • When I change to 'load', it does not populate the div at all. But when I use DOMContentLoaded, it throws alert first time, and then works subsequent times. `console.log(data)` returned nothing...no console output – Dhanvi Sreenivasan May 27 '16 at 19:44
  • Your code seems to work fine for me. [(link)](http://cthorne.me/d/stack.html) – libcthorne May 27 '16 at 19:53
  • Can you see what `searchQuery` is on the first call to `getVideo(searchQuery)` and compare it to the successful calls? Perhaps the first call is not passing in the expected data. – Karl Galvez May 27 '16 at 20:36
  • @cthorne, https://github.com/dhanvi97/track-u-tube/tree/dhanvi. Try using the full chrome extension, and please tell me the results. – Dhanvi Sreenivasan May 28 '16 at 00:26

2 Answers2

1

I tried your Chrome extension and managed to replicate this behaviour.

The problem is in the following code:

<form action="#">
    <input type="text" id="input"><br><br>
    <center><button id="search">Click Here!!</button></center>
</form>

Upon clicking the search button, the form is being submitted and reloading the page. The page reloads so your AJAX request is cancelled. This is what what giving you the readyState 0 error. One way you can tell this is happening is by noticing that the text from the text input disappears when you press the button.

To stop the reloading, you could use e.preventDefault() in the JavaScript like the page above suggests, but I think the most appropriate solution here is to add type="button" to your button:

<button id="search" type="button">Click Here!!</button>

You may wonder why this only happened on the first request. This comes down to how action="#" is handled and the answer is basically, not in any standard way that you can rely on. In fact, you can test here and see that Firefox doesn't reload the page at all, whereas Chrome does, but only the first time.

Community
  • 1
  • 1
libcthorne
  • 418
  • 3
  • 11
-1

Your problem seems to be that the data you're retrieving doesn't load in time in the first execution since AJAX calls are asynchronous. So when you call getIDs(data), data might not be loaded yet (which is why it's working on the subsequent calls).

One way you can resolve this issue is by using a promise. Rather than using success, you can do something like this:

    var ids; 

    $.ajax({
        url: queryURL,
        dataType: 'json',
        success: function(data) {   
            ids = data;
        },
        error: function(ts){
            alert(ts.responseText);
        }
    }).then(function(){   
            getIDs(ids); //calls this function *after* the data is retrieved
        });

This post on StackOverflow does a good job of explaining it.

Community
  • 1
  • 1
socialpiranha
  • 182
  • 1
  • 1
  • 10