Search code examples
javascriptgoogle-chromegoogle-chrome-extensionsoundcloud

Chrome Storage Sync get items in a persistent order


I'm working in a Chrome extension that stores a temporary playlist from items in SoundCloud to perform several actions on it later. So... I know Chrome Storage is an object and "can´t" be ordered per se, but I really need that order in any feasible way.

I tried storing objects in an Array and then Storing that Array in Storage after pushing a new element at the end of it and was the perfect workaround until, with 27 objects in it, Chrome told me that I had reached memory limit (I'm going to need more elements to store.) Storing each element as separate objects allows me virtually any amount of them (I think 50mb, which is enough for sure), but get method throws elements the way it wants (obviously, being an object). Objects are stored with timestamp keys, but still not working at all.

Is there a "light way" to do so? Code is not definitive and I'm thinking in appending elements directly to a new window, leaving storage calls for other stuff and move to "lighter" code, but would like first to know if this is somehow possible.

CODE - popup.js (here is where order is not persistent)

function appendTracks(){

    chrome.storage.sync.get(null, function (storageObject) {

//TODO check if is song
            $.each( storageObject, function( key, trackData ) {

              trackContainer(trackData["permalink"]);

            });

        });
}
function trackContainer(trackPermalink){
  console.log(trackPermalink);
  var trackWidget;
  $.getJSON(
  'http://soundcloud.com/oembed' +
  '?format=json' + 
  '&url='+trackPermalink+'&visual=false'
).done(function (embedData) { 
  trackWidget = embedData.html;
  $("#mainPlayList").append(trackWidget);
});
console.log(trackWidget);
return trackWidget;
}

CODE - main.js (Storage Setter with timestamp as key)

function downloadClick(a) {
    playListName = "";
    var b = this;
    $.ajax({
        url: a.data.reqUrl
    }).done(function(a) {

        var time = Date.now();
        var timeStamp = Math.round(time/1000);

        var key = timeStamp.toString()+"queueSc";

        var trackData = {
            "trackId" : a["id"],
            "trackTitle" : a["title"],
            "thumbnail" : a["artwork_url"],
            "streamUrl" : a["stream_url"],
            "permalink" : a["permalink_url"],
            "duration" : a["duration"],
            "genre" : a["genre"]};

        trackData[key] = "key";

        getStorage(null,function(storageObject){

            if(!isTrackInList(trackData,storageObject)){

            setStorage({
                    [key]: trackData 
            });

            }else{

                 console.log("ya esta en la lista"); 

            }

            });       
        
    })
}

function isTrackInList(trackData, storageObject){

    var isInList = false;
    $.each( storageObject, function( key, value ) {

        if(trackData["trackId"] == value["trackId"]){
            isInList = true;
        } 
    });

    return isInList;

}

I think is important to say that other than the order issue there is not any problem with it, everything runs fine, although there are things that could be more "elegant" for sure. Thanks in advance, hope you can help!


Solution

  • The problem is that you are exceeding the QUOTA_BYTES_PER_ITEM, i.e. the storage limit you are allowed per object. If you use chrome.storage.sync you are limited to 8,192 Bytes. Using chrome.storage.local will allow you to store unlimited size per item.

    Note using chrome.storage.local makes your data local to that machine and thus not synced across browsers on different machine.