1

I am trying to store a Range object, created from the text that user has selected, using chrome.storage.sync with the page URL as the key. Since, there can be multiple selections associated with a particular page, I am using an array to hold all the Range objects.

But I am unable to do it successfully. Each time I try to push a new Range object to the array, the previous objects become empty. Hence, I only get an array in which all objects are empty except for the last Range object that I pushed.

This is my code snippet:

var selectedRange = window.getSelection().getRangeAt(0); 
var key = request.url;
chrome.storage.sync.get([key], function(result){
    /*check if an object is already present in storage with this key*/
    if(Object.keys(result).length === 0 && result.constructor === Object){
        console.log("No entry for " + key + " present in storage");

        var entry = {}; 
        /*create a new array with the first Range object*/
        entry[key] = [selectedRange];
        chrome.storage.sync.set(entry, function(){
            console.log(entry);
        }); 
    } else {
        console.log("Entry found!");

        var value = result[key];
        /*push the Range object in the existing array*/ 
        value.push(selectedRange);

        chrome.storage.sync.remove(key, function(response){
            var entry = {}; 
            entry[key] = value;
            chrome.storage.sync.set(entry, function(){
                console.log(entry);
            }); 
        }); 
    }
});

Here's the output from my console when I add 3 objects one after the other:

output from the console when I add Range objects

What's even more weird is that if I simply try to store a string instead of the Range object, say, by using this definition for selectedRange,

var selectedRange = "SomeString";

the storing works exactly as expected. The documentation for storage API says that it can store user data as objects.


EDIT:

With the help of @wOxxOm , I have been able to locate the problem to the fact that chrome.storage api can only store JSONifiable objects but Range object is not JSONifiable.

I thought about creating a new object and storing just the startContainer, startOffset, endContainer and the endOffset properties. Then, I would've been able to recreate the Range object using the range.setStart(startNode, startOffset) and range.setEnd(endNode, endOffset) methods.

But then I found that even the Node objects are not JSONifiable! :(

It would be great if you could tell me a fix around this problem.

Thanks!

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
Nityesh Agarwal
  • 464
  • 2
  • 5
  • 18
  • As you can see in the documentation only JSON-ifiable objects are stored. To preview the result you can run JSON.parse(JSON.stringify(yourObject)). – wOxxOm Jun 25 '18 at 07:20
  • I added this statement: `selectedRange = JSON.parse(JSON.stringify(selectedRange));` and tried it again but now its only empty objects, even the last pushed object is empty now. – Nityesh Agarwal Jun 25 '18 at 09:03
  • I think the problem is with `JSON.stringify(selectedRange)`. I don't think its working. I tried `console.log(JSON.stringify(selectedRange))` and it just prints an empty object. What do you think @wOxxOm ? – Nityesh Agarwal Jun 25 '18 at 09:05
  • It simply means that `Range` is not JSON-ifiable so you can't save it in chrome.storage. – wOxxOm Jun 25 '18 at 09:06
  • Umm.. can you suggest something to work around that? – Nityesh Agarwal Jun 25 '18 at 09:09
  • There's no workaround. You'll need to think of another approach. Like maybe save the index of Range elements inside document.getElementsByTagName('*') array. – wOxxOm Jun 25 '18 at 09:10
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/173741/discussion-between-nityesh-agarwal-and-woxxom). – Nityesh Agarwal Jun 25 '18 at 09:52

0 Answers0