LocalStorage with Json.stringify not persisting - json

In it's simplest form:
localStorage.setItem('index0', JSON.stringify(playerInventory[lootArray[0]]));
var retrievedIndex0 = localStorage.getItem('index0');
console.log('retrieved0:'+retrievedIndex0 ); //Displays correct amount
So I thought it was working, but then if I don't setItem immediately before using getItem, it returns null, or if I setItem, hit F5, 'index0' becomes null...
if(localStorage.getItem('index0') < playerInventory[lootArray[0]]) {
console.log('bingo! ');
localStorage.setItem('index0', JSON.stringify(playerInventory[lootArray[0]])); }
This ^ will output 'bingo!' into the log (in firefox), but the setItem does not update localStorage. If I replay the game it'll be null if I don't setItem again before getItem...
This will fire correctly as well...
var oldscore = localStorage.getItem('index0');
var newscore = playerInventory[lootArray[0]];
if(oldscore < newscore) { console.log('new high score');}
But setItem will not update localStorage....and if I hit f5 and replay the game it'll be null
if(oldscore < newscore) {
console.log('new high score'); //This fires
localStorage.setItem('index0', JSON.stringify(playerInventory[lootArray[0]])); //this doesnt
}
if I go to my main update() loop, and put:
console.log(localStorage.getItem('index0')); //returns null
console.log(localStorage.getItem.index0); //returns undefined
Anyone see anything wrong, or have any other tests I could do?
playerInventory[lootArray[0]] is holding the number that I want to use compare with localstorage and update to localstorage when it's higher....I use that object to update divs on my screen with the current value so I know it's holding the integer that I want to save/restore.................................
I just tested in IE and it doesn't work at all it errors: Even the basic first part at the top of this post throws the error.
SCRIPT5007: Unable to get value of the property 'getItem': object is
null or undefined
I can set the item in the same function before using getItem and it's not null obviously at that moment but it doesn't persist beyond that point......

I was having similiar issues with this error when I was working on a project. I've noticed that when I attempted to just run my file, I would keep getting the error of being null or undefined. Once I put my project on a server, it worked.
Also, you already have a variable for the retrieved index. Try using that for your checks, then, if the score is higher, set the new score, if not, set the retrieved index back into local storage.
A note for IE, if you're getting errors when trying to getItem, IE won't go pass the errors in the current method/function. When trying to getItem in IE, throw a try catch around it.
I hope this can help.
Also, try using
localStorage.setItem('index0', JSON.stringify(newscore));
since you already have the variable created.

Related

Using Drive.Properties.update to update or add a file property

I have enabled the Advanced Drive Service in an apps script. For a file in Google Drive, I need to set metadata properties that may already exist, so I am trying to use the update method of Drive.Properties. This method is supposed to "Update a property or add it if it doesn't exist." (See Properties: update.)
The following code fails silently (with nothing logged to the Logger and no properties added to the file). However, if I step through these same lines, I do see the catch block executed every time.
var fileId = '1jgoihblahblahblah' /* an existing file id */;
var property = {key: 'TestKey', value: 'TestValue', visibility: 'PUBLIC'}
try {
Drive.Properties.update(property, fileId, "TestKey");
} catch (e) {
Logger.log(e);
}
If I replace the call to update with this line:
Drive.Properties.insert(property, fileId);
... then the code works every time. The properties are written and are returned by calling Drive.Properties.list(fileId).
Testing the same values using the API explorer (with real values or the "TestKey" and "TestValue" examples above) always works correctly, so I don't think it's simply a matter of providing bad data. UPDATE: The API explorer is now returning an error "Property keys may only contain letters, numbers, and the characters .!#$%^&*()-_/" no matter what values I pass in. However, there are obviously no invalid characters in key names like "TestKey" and "Link" (which is one of the actual keys I am using).
1) How can I troubleshoot the error from within the Script editor? I can't yet figure out how to retrieve the error text, since update fails silently even without the try/catch.
2) I am using the syntax specified by the autocomplete prompt, since there's not actually any documentation for Apps Script syntax for advanced service.
Is that syntax correct? If so, am I doing something wrong that I'm not seeing?
This problem is irrelevant because despite its name, Drive.Properties.insert does the same thing.
See https://issuetracker.google.com/issues/36759642

Do views immediately reflect data changes in their underlying tables?

I have a view ObjectDisplay that is composed of two relevant tables: Object and State. State represents the state of an Object, and the view pulls some of the details from the most recent State for each Object.
On the page that is displaying this information, a user can enter some comments, which creates a new State. After creating the new State, I immediately pull the Object from ObjectDisplay and send it back to be dropped into a partial view and replace the Object in the grid on the page.
// Add new State.
db.States.Add(new State()
{
ObjectId = objectId,
Comments = comments,
UserName = username
});
// Save the changes (executes all of the above).
db.SaveChanges();
// Return the new Object information.
return db.Objects.Single(c => c.ObjectId == objectId);
According to my db trace, the Single call occurs about 70 ms after the SaveChanges call, and it occurs on the same SPID.
Now for the issue: The database defaults the value of RecordDate in State to GETUTCDATE() - I don't provide the date myself. What I'm seeing is that the Object returned has the State's RecordDate of the old State and the Comments of the new State information of the old State. I am seeing that the Object returned has the old State's information. When I refresh the page, all the correct information is there, but the wrong information is returned in the initial call from the database/EF.
So.. what could be wrong? Could the view not be updating quickly enough? Could something be going on with EF? I don't really know where to start looking.
If you've previously loaded the same Object entity in the same DbContext, EF will return the cached instance with the stale values, and ignore the values returned from SQL.
The simplest solution is to reload the entity before returning it:
var result = db.Objects.Single(c => c.ObjectId == objectId);
db.Entry(result).Reload();
return result;
This is indeed odd. In SQL Server views are not persisted by default and therefore show changes in the underlying data right away. You can create a clustered index on a view with effectively persists the query, but in that case the data is updated synchronously, so you should see the change right away.
If you are working with snapshot isolation level your changes might not be visible to other SPIDs right away, but as you are on the same SPID and do not use snapshot isolation, this cant be the culprit either.
The only thing left at this point is the application layer. Are you actually using the result of the Single call higher up in the call stack or does that get lost somewhere. I assume that a refresh of the page uses a different code path, which would explain why it is working there.

IndexedDB - search index event.target.result always null

I can't figure out what's wrong with this snippet of code. I have an indexedDB instance. The keyPath is auto-generated. I can successfully add objects to the DB and get all objects in the DB, but I can't successfully search for an object in an index I created.
See my jsfiddle: http://jsfiddle.net/R5ngM/13/
Haven't nailed it perfectly yet but the issue seems to be that you're opening the cursor on your object store, rather than the index. With the default keyPath that works fine but it won't work when you're trying to use a secondary index.
What I think you're looking to do should look like:
var request = null;
if ( null === index || 'undefined' === typeof index ) {
request = transaction.openCursor( keyRange );
} else {
request = index.openCursor( keyRange );
}
request.onsuccess = on_success;
UPDATE: I spent a lot of time looking in the wrong place after finding the above issue with the index cursor. Here's the issue: The object you're storing is an array not an object literal.
I was looking into the object you were storing and noticed this:
var entry = '<li>'+row[0].fname+' '+row[0].lname+'</li>';
See how you're accessing the first element of the row array? You're storing an array. Your keypath (and me) assumed an object was stored. I believe it's possible to have an index on an array but in any case your keyPath is off.
Here's a largely-similar chunk of working code. I mucked it up a bit while debugging but you'll get the gist. (It's a nice snippit so if you don't mind, I'll use it as the base of other StackOverflow examples later on.)
Keep the cursor on the index as explained in my answer above. Then change to this line:
var entry = '<li>'+row[0].fname+' '+row[0].lname+'</li>';
And the change this:
var newUser = [{fname:$('#fname').val(),lname:$('#lname').val()}];
To this:
var newUser = {fname:$('#fname').val(),lname:$('#lname').val()};
It must also be noted that the above issue can even arise when you open a cursor on the index. If you open the cursor on index and still you always get null you should double check the data type that you created the index on and the the data type on which you're creating your index cursor on. In my case I'd created the index on string data-type and was opening a cursor on the index with int and it was driving me crazy.

Why do I get a DuplicateKeyException in Linq2Sql after I checked for the keys existence?

I have a program that adds a lot of new data to a database using Linq2SQL.
In order to avoid DuplicateKeyExceptions, I check for the existence of the key, before trying to add a new value into the database.
As of now, I can't provide an isolated test-case, but I have simplified the code as much as possible.
// newValue is created outside of this function, with data read from a file
// The code is supposed to either add new values to the database, or update existing ones
var entryWithSamePrimaryKey = db.Values.FirstOrDefault(row => row.TimestampUtc == newValue.TimestampUtc && row.MeterID == newValue.MeterID);
if (entryWithSamePrimaryKey == null)
{
db.Values.InsertOnSubmit(newValue);
db.SubmitChanges();
}
else if(entryWithSamePrimaryKey.VALUE != newValue.VALUE)
{
db.Values.DeleteOnSubmit(entryWithSamePrimaryKey);
db.SubmitChanges();
db.Values.InsertOnSubmit(newValue);
db.SubmitChanges();
}
Strangely enough, when I look at the exceptions in the application log, as to which items cause trouble, I am unable to find ANY of them in the database.
I suspect this happens within the update code, so that the items get removed from the database, but not added again.
I will update my code to deliver more information, and then update this post accordingly.
If the error is generated in the update block, you can merge the object in the update case without deleting entryWithSamePrimaryKey, but valorizing it with the property value of newValue and than save the changes.

Coldfuson CFScript "setSQL" method was not found

I've got a Coldfusion component, with a method in it called getColumnNames
This just queries a MySQL table, and returns the columnlist:
remote string function getColumnNames() {
qProcessCars = new Query();
qProcessCars.setDataSource('#APPLICATION.dsn#');
qProcessCars.setSQL('SELECT * FROM sand_cars WHERE 1 LIMIT 1');
qProcessCars = qProcessCars.Execute().getResult();
return qProcessCars.columnlist;
}
If I access this remotely in the browser, with page.cfc?method=getColumnNames, then I get the expected list of columns back.
However, if I try to access this from inside another method within the component, I get an error
remote string function otherFunction() {
...
sColumns = getColumnNames();
...
}
The error dump for the above code returns the message "The setSQL method was not found".
So can anyone help me find out why it works as a remote call, but not when called from another method inside the same component.
Problem may be caused some kind of race conditions. If you make few calls which interfere, at some point qProcessCars may already be query result, so invoking method is not possible.
I would try to make the qProcessCars variable local scoped (var qProcessCars = new Query();
) and/or try to use another variable name for query results.
Next possible step is to enclose the query building/executing code into named lock.
Ah I've answered my own question again. Sorry.
I've used the same name qProcessCars else where in the component, I hadn't put var in front of them.
I don't know WHY that was causing the problem, but it was. Maybe setSQL can only be called once per query object?