0

I am developing a chrome extension and after it is installed it iterates through opened tabs and if the required Tab is not found then I open a new tab. Following is my code:

var found = false;
chrome.tabs.getAllInWindow(null, function(tabs){
    for (var i = 0; i < tabs.length; i++) {
        var tabUrl = tabs[i].url;
        if (tabUrl == 'http://www.youtube.com') {
           chrome.tabs.update(tabs[i].id,{url:someUrl,selected:true});
           found = true;  
        }
    }
});
if (!found) {
    window.open('https://www.youtube.com/watch?v=somevideid');
}

The problem is that whether the youtube is found or not the NOT FOUND if condition always return true and the default video URL is opened where as it should only open if youtube tab is not found. I think the Last if condition is not at the right place, any idea?

asim-ishaq
  • 2,190
  • 5
  • 32
  • 55
  • @juvian I need to know about the execution of chrome.tabs.getAllInWindow function, does the next statement is exeuted after all code within this function executes? – asim-ishaq Oct 09 '14 at 19:28
  • 1
    `getAllInWindow` is asynchronous: you're executing the last two lines before the anonymous function. Move the last two lines into the anonymous function. Btw, `getAllInWindow` is [deprecated](https://developer.chrome.com/extensions/tabs#method-getAllInWindow). – Teepeemm Oct 09 '14 at 19:32
  • @teepeemm i thought of this but the function will be called multiple time for each window, the youtube link can be in any of the window. For the time I am thinking of wraping the second if in a setTimeout function. Any better solution? – asim-ishaq Oct 09 '14 at 19:38

1 Answers1

0

You should use chrome.tabs.query() instead of chrome.tabs.getAllInWindow(). The .query method, if called with an empty queryInfo object, will find ALL the tabs.

So, your code should be like this:

chrome.tabs.query({}, function(tabs) {
    var found = false;
    for (var i=0; i < tabs.length; i++) {
        if (/https?:\/\/www\.youtube\.com/.test(tabs[i].url)) {
            found = true;
            chrome.tabs.update(tabs[i].id, {url: 'https://www.youtube.com/watch?v=somevideid', active: true});
            break; // you found it, stop searching and update the tab
        }
    }

    if (!found) chrome.tabs.create({url: 'https://www.youtube.com/watch?v=somevideid', active: true});
    // you didn't find it, create a new tab with the new url and select it
});

Also, I used the regexp /https?:\/\/www\.youtube\.com/ to test the url of the tab, because the url may begin with "http" or "https", or may have some query string attached, like "?hl=en" or similars, so using tab[i].url == "http://www.youtube.com/" will not provide you absolute certainty of finding the tab.

Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
  • 2
    While the code in the answer is correct, you have not explained why it works. The fact that it works is not caused by replacing `chrome.tabs.getAllInWindow` with `chrome.tabs.query`, but by placing the code inside the callback. – Rob W Oct 09 '14 at 20:22
  • The OP clarified that, no matter the code inside the function, it will be executes several times using getAllInWindow method. So that's not about the position of the if statement in the code, but about the right method to use to retrieve the tabs, which is query. – Marco Bonelli Oct 09 '14 at 20:24
  • Using query instead of getAllInWindow will not solve the problem if `query` is called multiple times in the same way as getAllInWindow. The OP hasn't shown how they called the method, so we're left to guessing. The general and easiest solution to this problem is to use Promise + Promise.all + `.then`. – Rob W Oct 09 '14 at 20:28
  • Doesn't the `break` avoid the problem of executing several times? (Not that I know anything about Promises.) – Teepeemm Oct 09 '14 at 22:24
  • Promises are just something to avoid. You can't learn ti write good code using promises for this kind of stupid problems... by the way @RobW nope, the function with getAllInWindow would get called several times and the for loop would therefore be executed several time too, so the break is only to stop the iteration when you find the correct tab and don't waste time searching anymore. – Marco Bonelli Oct 10 '14 at 06:21
  • The query function works fine and satisfy the test case, thanks for the regular expression as well. – asim-ishaq Oct 10 '14 at 18:58