mildlyinfuriated22
mildlyinfuriated22

Reputation: 41

Having trouble with basic greasemonkey script - GM.getValue / GM.setValue (I think)

I'm trying to write a basic Greasemonkey script but I'm running into some problems. Essentially, the script will refresh the page and count the number of images on a page. If the number of images increased, it will alert me and make that tab active. If the number of images are the same or less, it will continue refreshing the page at set intervals.

I think that the best course of action, based on what I've looked at, would be to use GM.getValue / GM.setValue in order to store the number of images to compare it with the new image count. I just can't seem to get it to even run though - I think my logic is sound, but it's just a syntax issue despite trying different variations. I've never used Javascript before!

// ==UserScript==
// @name        *Page Refresher
// @include     *
// ==/UserScript==
// @grant    GM.getValue
// @grant    GM.setValue

var refreshRate = 10000; //Refreshes every 10s
var newCount =document.images.length; //Counts images on page

if (GM.getValue('oldCount',-1) === -1){
  GM.setValue('oldCount',newCount);
  window.setTimeout(function(){window.location.reload() ;},refreshRate);
} else {
  if (newCount <= GM.getValue('oldCount')){
      GM.setValue('oldCount',newCount);
      window.setTimeout(function(){window.location.reload() ;},refreshRate);
} else {
     if (newCount > GM.getValue('oldCount')){
         GM.setValue('oldCount',newCount);
         alert('More images!');
      }
}

That's the rough code I'm working with. I'm just not really sure where I'm going wrong - I'm sure it's something pretty straightforward, but I'm definitely struggling. Thank you!

Upvotes: 4

Views: 1555

Answers (1)

erosman
erosman

Reputation: 7721

Those functions (like GM.getValue) in GM4 are asynchronous. That means the value they return is not immediately available like in synchronous API.

In asynchronous code, you need to wait for the response.

Note: You should get the value of oldCount once and cache it instead of getting over and over from stored value. There is also an error in the Metadata Block.

Here is an example based on your code (code simplified)

// ==UserScript==
// @name        Page Refresher
// @include     *
// @grant       GM.getValue
// @grant       GM.setValue
// ==/UserScript==

(async () => {

  const refreshRate = 10000;                      // Refreshes every 10s
  const newCount = document.images.length;        // Counts images on page
  const oldCount = await GM.getValue('oldCount', -1);

  await GM.setValue('oldCount', newCount);        // save new value, wait since refreshing before saving can cause issues

  if (newCount > oldCount){ 
    alert('More images!'); 
  } 
  else { 
    setTimeout(() => { location.reload(); }, refreshRate); 
  } 

})();

Upvotes: 2

Related Questions