Search code examples
greasemonkey-4

Greasemonkey Get and Set Value not working and killing script with no error


I'm trying to store some values that will persist through page loads and browser closing in Greasemonkey. My code is as follows:

// @name     Netflix saw it button
// @description     Apparently Netflix can't afford enough storage space or programmers to make it easy to know which shows you've seen before. This fixes that. Unfortunately, it will only store data in one browser at a time so you have to use the same computer and browser for the data to store. Sorry about that, but I'm not a Netflix tech so this is the best we got.
// @version  1
// @include     https://www.netflix.com/*
// @grant    none
// @grant    GM.getValue
// @grant    GM.setValue
// @require https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js 
// ==/UserScript==


$(document).ready(function() {  
  $('[data-tracking-uuid]').each(function(){
    id= $(this).data('tracking-uuid');
    console.log(id);
    console.log(typeof id);
    GM.setValue(id,1);
    console.log(GM.getValue(id));
    if(GM.getValue($(this).data('tracking-uuid')))
      $(this).closest('.title-card-container').addClass('g_watched');
  });
});

As you can see, I'm testing persistant storage, but it's not giving me the results I'd expect. When I check the console, I can see the id and the id's type is string (which GM.setValue requires). On the very next line when it tries to set the value, it stops executing JS and no other lines run. No error is thrown. It just dies.

It was the same when I didn't have the setvalue there and just had getvalue (which should return null if it hasn't been set before). What am I doing wrong? This is Greasemonkey > 4.0 so this should be the proper syntax, but without any kind of error or feedback, I'm stuck.


Solution

  • GM.getValue & GM.setValue are async which means you have to wait for it, before moving on.

    An example to explain the process:

    // set  value
    GM.setValue(id,1);            // async operation
    // script runs but value is still in the process of setting
    const a = GM.getValue(id);    // async operation
    // script runs but value is still in the process of getting
    console.log(a);               // a is not set yet
    

    How to fix the above async issue

    (async() => {
      
      // set  value
      await GM.setValue(id,1);          // async opertaion wait for it before moving on
      const a = await GM.getValue(id);  // async opertaion wait for it before moving on
      console.log(a);                   // a is avialble
    
    })();
    

    Here is an example of your script with async/await
    Firstly, @grant none conflicts with @grant GM.getValue etc

    // @name          Netflix saw it button
    // @description   Apparently Netflix can't afford enough storage space or programmers to make it easy to know which shows you've seen before. This fixes that. Unfortunately, it will only store data in one browser at a time so you have to use the same computer and browser for the data to store. Sorry about that, but I'm not a Netflix tech so this is the best we got.
    // @version       1
    // @include       https://www.netflix.com/*
    // @grant         GM.getValue
    // @grant         GM.setValue
    // @require       https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js 
    // ==/UserScript==
    
    
    $(document).ready(async function() {  
      $('[data-tracking-uuid]').each(function(){
        id= $(this).data('tracking-uuid');
        console.log(id);
        console.log(typeof id);
        await GM.setValue(id,1);
        console.log(await GM.getValue(id));
        if(await GM.getValue($(this).data('tracking-uuid')))
          $(this).closest('.title-card-container').addClass('g_watched');
      });
    });