Properly storing an object in chrome.storage? - javascript

I'm trying to store an object in my chrome extension containing other objects using chrome.storage - but am having trouble initializing it and properly fetching it using chrome.storage.sync.get. I understand that I'm supposed to get objects in the form of chrome.storage.sync.get(key: "value", function(obj) {} - the issue is I'm not sure how to
Initialize the object the first time with get
Properly update my object with set
I have the following code to create the object and add the data I need.
allData = {};
currentData = {some: "data", goes: "here"};
allData[Object.keys(allData).length] = currentData;
This will correctly give me an object with it's first key (0) set to currentData. (Object: {0: {some: "data", goes: "here"}}) Working as intended, and allData[Object.keys(allData).length] = currentData; will properly push whatever currentData is at the time into my Object later on.
But how do I properly store this permanently in chrome.storage? chrome.storage.sync.get("allData", function(datas) {}) fails to create an empty allData variable, as does allData: {}, allData = {}, and a variety of different things that return either undefined or another error. How do I properly initialize an empty object and store it in chrome.storage? Or am I going about this all wrong and need to break it down into associative arrays in order for it to work?
I essentially need that small block of working code above to be stored permanently with chrome.storage so I can work with it as needed.

You first need to set the data inside the storage:
allData = {};
currentData = {some: "data", goes: "here"};
// to initialize the all data using the storage
chrome.storage.sync.get('allData', function(data) {
// check if data exists.
if (data) {
allData = data;
} else {
allData[Object.keys(allData).length] = currentData;
}
});
// Save it using the Chrome extension storage API.
chrome.storage.sync.set({'allData': allData}, function() {
// Notify that we saved.
message('Settings saved');
});
After that you should be able to access the data using the chrome.storage.sync.get('allData', function(){ ... }) interface.

You can easily do this with the new JavaScript (ECMAScript 6), have a look into Enhanced Object Properties:
var currentData = {some: "data", goes: "here"};
chrome.storage.local.set({allData: currentData });
In the old way, was something like this:
var obj = {};
var key = "auth";
obj[key] += "auth";
obj[key] = JSON.stringify({someKey: someValue});

Related

How to store multiple items in Chrome Extension Storage? [duplicate]

I'm writing a chrome extension, and I can't store an array. I read that I should use JSON stringify/parse to achieve this, but I have an error using it.
chrome.storage.local.get(null, function(userKeyIds){
if(userKeyIds===null){
userKeyIds = [];
}
var userKeyIdsArray = JSON.parse(userKeyIds);
// Here I have an Uncaught SyntaxError: Unexpected token o
userKeyIdsArray.push({keyPairId: keyPairId,HasBeenUploadedYet: false});
chrome.storage.local.set(JSON.stringify(userKeyIdsArray),function(){
if(chrome.runtime.lastError){
console.log("An error occured : "+chrome.runtime.lastError);
}
else{
chrome.storage.local.get(null, function(userKeyIds){
console.log(userKeyIds)});
}
});
});
How could I store an array of objects like {keyPairId: keyPairId,HasBeenUploadedYet: false} ?
I think you've mistaken localStorage for the new Chrome Storage API.
- You needed JSON strings in case of the localStorage
- You can store objects/arrays directly with the new Storage API
// by passing an object you can define default values e.g.: []
chrome.storage.local.get({userKeyIds: []}, function (result) {
// the input argument is ALWAYS an object containing the queried keys
// so we select the key we need
var userKeyIds = result.userKeyIds;
userKeyIds.push({keyPairId: keyPairId, HasBeenUploadedYet: false});
// set the new array value to the same key
chrome.storage.local.set({userKeyIds: userKeyIds}, function () {
// you can use strings instead of objects
// if you don't want to define default values
chrome.storage.local.get('userKeyIds', function (result) {
console.log(result.userKeyIds)
});
});
});

Firebase DB updating and pushing simultaneously

Is there any way to update and push simultaneously?
I want to update a key2 in my object and simultaneously push unique keys under timeline in a single request ref().child('object').update({...}).
object
key1:
key2: // update
key3:
timeline:
-LNIkVNlJDO75Bv4: // push
...
Is it even possible or one ought to make two calls in such cases?
Calling push() with no arguments will return immediately (without saving to the database), providing you with a unique Reference. This gives you the opportunity to create unique keys without accessing the database.
As an example, to obtain a unique push key, you can do some something like:
var timelineRef = firebase.database().ref('object/timeline');
var newTimelineRef = timelineRef.push();
var newTimelineKey = newTimelineRef.key;
With this, you can then perform a multi-level update which makes use of the new key:
var objectRef = firebase.database().ref('object');
var updateData = {};
updateData['object/key2'] = { key: 'value' };
updateData['object/timeline/' + newTimelineKey] = { key: 'value' };
objectRef.update(updateData, function(error) {
if (!error) {
console.log('Data updated');
}
});

Getting array values from multidimensional array in JavaScript

I'm in need of some minor assistance. I'm having trouble getting an array (larray3) populated with two other array objects (larray1 and larray2) to pass both from data.js into the subsequent model.js and view.js. Data.js correctly builds the multidimensional array however when the results are received in model.js/view.js I only receive the results for larray1. Because only the first values come thru I cannot tell if both larray1 and larray2 are actually passing thru. Can someone please tell me how I should alter my syntax in either model.js or view.js to access both array values or what else I could change? Thank you in advance.
data.js.
function getCountries(done) {
var sqlite3 = require('sqlite3').verbose();
var file = 'db/locations.sqlite3';
var db = new sqlite3.Database(file);
var larray1 = [];
var larray2 = [];
var larray3 = [];
db.all('SELECT * FROM Country', function(err, rows) {
// This code only gets called when the database returns with a response.
rows.forEach(function(row) {
larray1.push(row.CountryName);
larray2.push(row.CountryCode);
})
larray3.push(larray1);
larray3.push(larray2);
return done(larray3[0], larray3[1]);
});
db.close();
}
model.js
function Countries(done) {
//Pull location values from data
return getCountries(done);
}
view.js
function viewCountries() {
var viewCou = Countries(function(results) {
// Code only gets triggered when Countries() calls return done(...);
var container = document.getElementById('country-select');
var fragment = document.createDocumentFragment();
results.forEach(function(loc, index) {
var opt = document.createElement('option');
opt.innerHTML = loc;
opt.value = loc;
fragment.appendChild(opt);
});
container.appendChild(fragment);
})
}
In data.js you send two arguments to the done callback:
return done(larray3[0], larray3[1]);
This done function is passed through in your model.js:
return getCountries(done);
And that done is passed in from view.js:
Countries(function(results) { // ...
So it is this anonymous function (function(results) {...}) that is called in data.js. But notice that this function only has one parameter, so you're doing nothing with the second argument that data.js sends. result gets the value of larray3[0], but larray3[1] is not captured anywhere.
You could solve this in different ways. Personally, I think the design with two arrays is wrong from the start. I would not separate data that belongs in pairs (name and code) into two different arrays.
Instead make an array of objects, and pass that single array around:
In data.js:
rows.forEach(function(row) {
larray1.push({
name: row.CountryName,
code: row.CountryCode
});
})
return done(larray1);
In view.js:
opt.textContent = loc.name;
opt.value = loc.code;
Side-note: .textContent is preferred over .innerHTML when assigning plain text.

Local storage saving multiples of the same items

I'm quite new to using storage settings in HTML/JavaScript. I'm building a hybrid app which is a not taking app on mobile using Phonegap. I want the user to type in a note name, then the note itself, and be able to save both by placing them into a jquery mobile list and putting them back on the home screen. My problem is that I can only save one note at a time. If I try to save another one, it just overwrites the previous one. How would I go about fixing it? Also, when I try refresh the browser the note disappears. Is this normal?
Please and thank you.
Here is the saving function I used:
function storeData() {
var i;
for (i=0; i<999; i++) {
var fname = document.getElementById('fname').value;
var wtf = document.getElementById('wtf').value;
localStorage.setItem('fname', fname);
localStorage.setItem('wtf', wtf);
}
var newEl = "<li><a href='#' id='savedNote'onclick='loadData'></a></li>"
document.getElementById("savedNote").innerHTML = localStorage.getItem("fname");
//try to create a new list element in main menu for this item being stored in
// and add an onclick load function for that
};
function loadData() {
var x;
for (x=0; x<999; x++) {
document.getElementById("fname").innerHTML = localStorage.getItem('fname', fnamei);
document.getElementById("wtf").innerHTML = localStorage.getItem('wtf', wtfi);
}
};
I'm not sure why you're using a loop for your functions. The storeData function looks 999 times for the value of #fname and #wtf, and save this 999x times in localStorage.fname and localStorage.wtf
This makes absolut no sense. Same Problem with your loadData function.
A nice way to save more then one string to the localStorage, is to create a javascript object, stringify it and then save it to the localStorage.
You only need to load the data from the localStorage, if you (re)load the page. But you need to save it to the localStorage, every time something changed, to be sure that the data in the localStorage is always up to date.
For display and manipulation on the page, you use the javascript object. in my example "myData". If you change something, you update your javascript object and then save it to the localStorage.
a side note. to be sure that the user don't overwrite something with a
identical name, you should use unique ids. like i did with the timestamp.
var postID = new Date().getTime();
Here a little example to show you a possible way. It's hard to code something functionally without your html code.
// Creating a object for all Data
var myData = {};
// Fill the Object with data if there is something at the LocalStorage
if (localStorage.myData){
loadDataFromLocalStorage();
}
function createNewPost(){
// Create a ID for the Post
var postID = new Date().getTime();
// Create a Object inside the main object, for the new Post
myData[postID] = {};
// Fill the Object with the data
myData[postID].fname = document.getElementById('fname').value;
myData[postID].wtf = document.getElementById('wtf').value;
// Save it to the LocalStorage
saveDataToLocalStorage();
// Display the Listitem. with the right postID
}
function loadPost (postID){
var singlePost = myData[postID];
// Display it
}
// A Helper Function that turns the myData Object into a String and save it to the Localstorage
function saveDataToLocalStorage(){
localStorage.myData = JSON.stringify(myData);
}
// A Helper Function that turns the string from the LocalStorage into a javascript object
function loadDataFromLocalStorage(){
myData = JSON.parse(localStorage.myData);
}
// Creating a object for all Data
var myData = {};
// Fill the Object with data if there is something at the LocalStorage
if (localStorage.myData){
loadDataFromLocalStorage();
}
function createNewPost(){
// Create a ID for the Post
var postID = new Date().getTime();
// Create a Object inside the main object, for the new Post
myData[postID] = {};
// Fill the Object with the data
myData[postID].fname = document.getElementById('fname').value;
myData[postID].wtf = document.getElementById('wtf').value;
// Save it to the LocalStorage
saveDataToLocalStorage();
// Display the Listitem. with the right postID
}
function loadPost (postID){
var singlePost = myData[postID];
// Display it
}
// A Helper Function that turns the myData Object into a String and save it to the Localstorage
function saveDataToLocalStorage(){
localStorage.myData = JSON.stringify(myData);
}
// A Helper Function that turns the string from the LocalStorage into a javascript object
function loadDataFromLocalStorage(){
myData = JSON.parse(localStorage.myData);
}
Store an array.
var arrayX = [];
arrayX.push(valueY);
localStorage.setItem('localSaveArray', arrayX);

Firebase - How to get list of objects without using AngularFire

Firebase - How to get list of objects without using AngularFire
I'm using typescript, angular2 and firebase.
I'm not using angularfire. I want to extract the data using their Api
My firebase url is /profiles
This is the list of profiles I'm looking to extract:
Thanks.
Use a simple value event and re-assign the array every time the value changes.
JSBin Demo.
var ref = new Firebase('https://so-demo.firebaseio-demo.com/items');
ref.on('value', (snap) => {
// snap.val() comes back as an object with keys
// these keys need to be come "private" properties
let data = snap.val();
let dataWithKeys = Object.keys(data).map((key) => {
var obj = data[key];
obj._key = key;
return obj;
});
console.log(dataWithKeys); // This is a synchronized array
});

Categories