Building Chrome Browser Extension - Error: "Cannot read property 'hubUrl' of null

Trying to build a Chrome Browser Extension that should send data to the Gaia storage of the logged in user. Unfortunately getting for putFile as well as for getFile errors.
When I run the exact same build code “outside” of the Chrome Extension environment in the browser the code works fine.

For getFile the error is:

Uncaught TypeError: Cannot read property 'hubUrl' of null
    at c (index_bundle.js:1)
    at t.getOrSetLocalGaiaHubConnection (index_bundle.js:1)
    at t.getFile (index_bundle.js:1)
    at t.value (index_bundle.js:1)
    at t.value (index_bundle.js:1)
    at Vp (index_bundle.js:1)
    at Dh (index_bundle.js:1)
    at HTMLUnknownElement.e (index_bundle.js:1)
    at Object.b (index_bundle.js:1)
    at invokeGuardedCallback (index_bundle.js:1)

For putFile the error looks like this:

Error:  TypeError: Cannot read property 'hubUrl' of null
    at c (index_bundle.js:1)
    at t.getOrSetLocalGaiaHubConnection (index_bundle.js:1)
    at t.putFile (index_bundle.js:1)
    at index_bundle.js:1

Does anyone have an idea how I could fix this?

Thanks so much for helping out! :pray:

Extensions don’t always work like their web-page counter parts. Can you give us some more details on how it’s set up?

I.E. is it running off the background page, an extension page, or the popup? Could you provide a snippet of the code itself and the relevant portion of your manifest.json? What’s your build system look like (webpack, something else)? If you are using webpack, could you turn the devtool to inline-source-map that way we can get exactly what line of code is in error isntead of “index_bundle.js”?

1 Like

Thanks Michael for looking into this, highly appreciated.

The basic usecase is about enabling the user with the extension to upload a parsed version of the current webpage to her text library.
The extension works as popup. Things are build with webpack.

The Manifest.json

{
  "short_name": "TL",
  "name": "TextLibrary",
  "manifest_version": 2,
  "browser_action": {
    "default_popup": "index.html",
    "default_title": "TextLibrary Add Text"
  },
  "version": "1.0",
  "description": "A browser extension to add texts from the web to your library."
}

As example the relevant fetchData part with the “getFile” is this:

fetchData() {
  this.setState({ isLoading: true })
  const options = { decrypt: false, verify: false, zoneFileLookupURL: 'https://core.blockstack.org/v1/names/' }
  getFile(textsFileName, options)
    .then((file) => {

      var arrTexts = JSON.parse(file || '[]');
      var collections = [...new Set([].concat(...arrTexts.map(o => o.tags)))];
      this.setState({
        collections: collections,
        arrTexts: arrTexts,
      })
    })
    .finally(() => {
      this.setState({ isLoading: false })
    })
  };

@wbobeirne answered in the Slack chat that things break here: https://github.com/blockstack/blockstack.js/blob/5aad42b00f975c8191f1f6ef6b59c77ea6f94dfd/src/storage/hub.js#L116 userData is null in this case.

Where you able to get it solved?

Otherwise it’s quite interesting, as this might be what’s causing the issue:

export function loadUserData() {
  return JSON.parse(window.localStorage.getItem(BLOCKSTACK_STORAGE_LABEL))
}

(source)

IIRC WebExtensions aren’t supposed to use window/localstorage, but instead should use the chrome.storage or browser.storage instead.

You could try messing around with “restoring” the local storage from the extension-storage as that may be the issue if you haven’t solved it yet.

1 Like

No, I haven’t solved it yet. @jude was mentioning there might be a hackish solution…

Sorry for the follow up… as React newbie … have to take any chance I get :wink:
Can you point me anywhere how I can tinker with this?

My hackish solution is to emulate just enough of localstorage and window.location to get this to work. Sample code here: https://github.com/blockstack/blockstack.js/issues/500

2 Likes

I would follow @jude 's resolution as it seems to work =)

Also this issue that he raised would solve your problem when it gets resolved.

Best of luck!

Jude, thanks so much again for taking the time.

I tried to tinker with the code examples provided in the GitHub issue and added them into my index.js as suggested.
Also updated the Blockstack version to “^18.0.4”.

Unfortunately I got at first this error:
Uncaught ReferenceError: blockstack is not defined .

When I tried to import blockstack from blockstack.js, then I got this one:
Uncaught TypeError: Cannot read property 'makeAuthResponse' of undefined

As mentioned above, I have to be honest, I am not really sure what I am doing here, ;( , … so please forgive me.
It would be really cool if that browser extension could work. :crossed_fingers:
Thanks again for all your help!

Just wanted to let you know that I built this morning a bookmarklet “solution” for this usecase… It kind of does the trick as well… at least for the beginning … so the Chrome Extension has no high priority anymore. No need to look into this immediately…

Jude, thanks again!

‘Undefined’ is the property of the global object. This error occurs in Chrome Browser when you read a property or call a method on an undefined object . Uncaught TypeError: Cannot read property of undefined error is probably easiest to understand from the perspective of undefined, since undefined is not considered an object type at all (but its own undefined type instead), and properties can only belong to objects within JavaScript. There are a few variations of this error depending on the property you are trying to access. Sometimes instead of undefined it will say null. If you get undefined error, you need to make sure that which ever variables throws undefined error, is assigned a value to it.