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.
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');
});
});