Using AngularJS to process custom localStorage data - javascript

I wrote a bookmarklet that retrieves information from a page and stores it in JSON format in local storage (converting it to a string first, of course).
I would like a web app I am writing to be able to process this data, on the fly, preferably as it gets saved to the localStorage.
Right now i can change the item in LS via the console and refresh the page and the new data appears but I would like it to be live and seamless.
Any advice on how to go about this? I found several localStorage modules for angularJS and I tried them but they don't seem to allow me to retrieve from LS if the data is already there in LS.
In response to answer:
$scope.$watch(
function(){
return $window.localStorage.getItem('TestData');
},
function(newValueInStorage){
$scope.testingLS = newValueInStorage;
}
)
I tried this and I still get the data displayed by just doing a {{ testingLS }} in the view template but when I go and change the TestData key in local storage via the console it doesn't update instantly. (for now, I am just testing it without the bookmarklet with just a simple string inside TestData

There is few ways to do it
One of will be to populate correct model on scope when saving to localStorage
The other that I can think of at this moment is to setup watcher
$watch(
function(){
return localstorage object
},
function(newValueInStorage){
$scope.modelFromLS = JSON.parse(newValueInsStorage)
}
)
---edit---
as per James comment you need something that will handle the fact that data has changed in different tab and $digest process need to run for watch to be recalculated
http://plnkr.co/edit/zlS3wL65meBeA8KkV5KH?p=preview
window.addEventListener('focus', function(){
console.log('focus')
$scope.$digest()
})

Related

Attempting to use a global array inside of a JS file shared between 2 HTML files and failing

So I have one HTML page which consists of a bunch of form elements for the user to fill out. I push all the selections that the user makes into one global variable, allTheData[] inside my only Javascript file.
Then I have a 2nd HTML page which loads in after a user clicks a button. This HTML page is supposed to take some of the data inside the allTheData array and display it. I am calling the function to display allTheData by using:
window.onload = function () {
if (window.location.href.indexOf('Two') > -1) {
carousel();
}
}
function carousel() {
console.log("oh");
alert(allTheData.toString());
}
However, I am finding that nothing gets displayed in my 2nd HTML page and the allTheData array appears to be empty despite it getting it filled out previously in the 1st HTML page. I am pretty confident that I am correctly pushing data into the allTheData array because when I use alert(allTheData.toString()) while i'm still inside my 1st HTML page, all the data gets displayed.
I think there's something happening during my transition from the 1st to 2nd HTML page that causes the allTheData array to empty or something but I am not sure what it is. Please help a newbie out!
Web Storage: This sounds like a job for the window.sessionStorage object, which along with its cousin window.localStorage allows data-as-strings to be saved in the users browser for use across pages on the same domain.
However, keep in mind that they are both Cookie-like features and therefore their effectiveness depends on the user's Cookie preference for each domain.
A simple condition will determine if the web storage option is available, like so...
if (window.sessionStorage) {
// continue with app ...
} else {
// inform user about web storage
// and ask them to accept Cookies
// before reloading the page (or whatever)
}
Saving to and retrieving from web storage requires conversion to-and-from String data types, usually via JSON methods like so...
// save to...
var array = ['item0', 'item1', 2, 3, 'IV'];
sessionStorage.myApp = JSON.stringify(array);
// retrieve from...
var array = JSON.parse(sessionStorage.myApp);
There are more specific methods available than these. Further details and compatibility tables etc in Using the Web Storage API # MDN.
Hope that helps. :)

What order do Google Chrome Sync Storage 'Get' Commands run?

I am having a very difficult time getting the timing of a simple counting process down.
When I use console.log and alerts to debug, it seems that the code runs randomly - not in the order it appears in the function.
I'm creating a Google Extension and using sync storage to store settings and retrieve them to update values for the user.
For instance, I'm trying to stuff a string into "localBody" so I can then count the words in the string.
So first up in background.js is a listener that fires when a specific sync variable is changed...and it pulls a value from sync storage:
chrome.storage.onChanged.addListener(function(changes, sync) {if (changes["Clabel"]){alert("Label Changed - start listener update...");
//Get body, label, group from Sync Storage
chrome.storage.sync.get('Cbody', function (results) {
localBody = results.Cbody;
console.log("first pulling body string from sync storage" + localBody);
});
Later in the code localBody is sent off to a sub that counts words in the string:
wordCount = wordCount + countWords(localBody); //Update total word count with latest addition
This code fails ("extensions::uncaught_exception_handler:8 Error in event handler for storage.onChanged: TypeError: Cannot read property 'replace' of undefined") and the console shows that it runs BEFORE the sync storage "get" command.
I have tried to do this basic task a zillion ways and I continually run into the unpredictability of pulling from sync storage. I don't know how to get around this - I need to pull a value and modify it, then stuff it back into sync storage.
Okay, for the bozos like me who are blundering along trying to build Google Extensions with only cursory knowledge of javascript...
The "Get" process is asynchronous. So you need to use callbacks to control when the value you want will be available.
This is a good explanation - I used the example code verbatim:
Chrome.storage.sync.get not storing value in local variable

Saving and accessing API results in a variable in Chrome extension

I'm making a Chrome extension that pulls a large amount of data from an API and uses it to modify content on a page. Because the amount of data is so large, I'd like to be able to save it once in the browser and be able to access it instead of doing an API call each time a page loads.
It's my understanding this can be done by putting the API call in the background page and then calling the variable from the background page in the content script. I've also tried storing the data in local storage. Neither method is working for me and I don't understand what I'm doing wrong.
In my code in the background page, I have the API results stored in a variable. I'm calling it in the content script like this:
var background = chrome.extension.getBackgroundPage();
var myData = background.APIData; //where APIData is the variable I set in the background page
My attempt to use local storage looks like this:
//Background page
chrome.storage.sync.set({'value': APIData}, function() {
// Notify that we saved.
console.log('APIData saved to storage');
});
//Content script
var myData = localStorage["APIData"];
As of this moment, the extension isn't even loading in the page using the code where I'm trying to access local storage. The extension will load with the other method but the data doesn't seem to be there. I know my API call is working because the extension works when I put it all in the content script. But that creates the problem where I'm calling the API each time the page loads. Help please!
Examine your code closely. You are setting the data to two different bins.
First, you call chrome.storage.sync.set and set "value" to the value of APIData.
Second, you call localStorage['APIData'] which refers to a separate storage bin and property name.
Two solutions here, the first being the preferred way to set/get persistent data in a Chrome extension:
A1) set it with chrome.storage.sync.set( { value:data } )
A2) get it with chrome.storage.sync.get( null, function( storage ){ storage.value } )
B1) set it with localStorage.value = data
B2) get it with localStorage.value

get jquery.data() related to an element from a saved html using javascript or jquery

I have some html that I want to save in database for a later retrieve.
Let's imagine the html is a simple div
<div id="mydiv">This is my div</div>
I use jQuery.data() to store some information related to that div like this :
$("#mydiv").data("divNumber", "5").data("divRole", "adminMessage") .....
Then finally I save the html in database, but I would like to be able to get those information later when I need them :
var myHtml = { here I get the html from my database }
$("body").append(myHtml);
console.log( $("#mydiv").data("divNumber") ); // I want it to show 5
console.log( $("#mydiv").data("divRole") ); // I want it to show adminMessag
from my understanding of jquery.data() I think it will just store those data information temporary in an internal cache and if I save the html in the database, and I leave the page, they will be lost !!
So is there a way to keep those jquery.data() information and retrieve them whenever I want ? or maybe there is another "better" way to achieve the same thing (I am not looking for localStorage method)
You can convert the .data() to data attributes on the html and save that.
$("#mydiv").data("divNumber", "5").data("divRole", "adminMessage");
$.each($("#mydiv").data(), function(k,v){
$("#mydiv").attr("data-"+k.replace(/[A-Z]/g, "-$&"), v);
});
var toDatabase = $("#mydiv")[0].outerHTML;
//save to database
// ...
// retrieve from database
var fromDatabase = $(toDatabase);
$('body').append(fromDatabase.data('divNumber'));
$('body').append('<br>');
$('body').append(fromDatabase.data('divRole'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mydiv">This is my div</div>
If you want to have a database in the browser which works across all platforms consistently, despite each browser having different underlying storage mechanisms try PouchDB. It is great! You can keep it just in your browser session which will persist until the user clears their data OR you can have it persist to a CouchDB database server.
http://pouchdb.com/
There are many good CouchDB providers if you dont want to setup your own although that is simple to do. IBM Cloudant is free until your usage is above $50 per month:
https://cloudant.com/
It is very simple to use, see here. A couple lines of code to create a db object and a few to put / fetch. Then one line each to setup a remote copy and one line to live sync to it.

How to save multiple objects to an array in a chrome extension?

I'm building my first chrome extension and I want it to track the TV series I watch and I'm currently trying to get it to save metadata on the series that I am following.
I have a content script that returns the title, the newest episode (and the URL of this episode) as well as the URL of the cover image of the series. I am currently trying to save it with some code on my background script (I have made sure to include "storage" under the permissions section of the manifest file).
So far my script looks like this (This was developed with help from Trying to save and fetch a Javascript object using chrome.storage API?):
var bkg = chrome.extension.getBackgroundPage();
response.aID = new Series(response.aTitle,response.aNewEp,response.aNewEpURL,response.aImage);
chrome.storage.sync.set(response.aID, function(){
chrome.storage.sync.get(function(val){
bkg.console.log("The saved title is: ", val.anTitle);
bkg.console.log("The saved newEp is: ", val.anNewEp);
bkg.console.log("The saved newEpURL is: ", val.anNewEpURL);
bkg.console.log("The saved imageURL is: ", val.anImage);
});
});
Problem is, the script only seems to store one response.aID at a time, so I can never store data for more than 1 TV series. Every time I try, the script seems to overwrite my previous entry. So I would like to ask whether there's any way to store more than 1 TV series at a time?
I have looked at storing an array and then pushing each new object into that array (Store an array with chrome.storage.local), but I don't quite understand the syntax involved so I'm not sure if this would work for me.
Unfortunately you didn't include the piece of code where you save your data, but i think you dont store your data with indices for the different TV series so the stored one gets overwritten everytime you store another one.
Anyway I would prefer storing your data in a JSON element (basically every javascript element can by converted to one but continue reading) because js provides several functions for this format which make it quite easy to use.
When opening your extension, load the data and call
var data = JSON.parse (yourloadedstring);
so the string (which should look like {"TVShows": [{"title": "How i met your mother", "url": ...}, {...}]} (look here for an explenation how JSON works) gets "translated" to an element from which you can read simply by calling
data.TVShows[0].title
or
data.TVShows[1].imageURL
You can edit this data JSON element when you add a new show for example by saying
data.TVShows[2].title = "The Big Bang Theory";
data.TVShows[2].URL= ...;
data.TVShows[2].imageURL= ...;
and save this element to chromes storage by calling
var dataToSave = JSON.stringify(data);
You have a string in your storage then, containing all information you need and you can simply parse it later like explained above :)
I hope everything is clearly to understand, if not pls ask me!
Cheers

Categories

Resources