IndexedDB - search index event.target.result always null - html

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.

Related

Cannot convert undefined or null to object - DynamoDB

Been testing some Lambda functions and finally managed to get the data to push to DyanmoDB, or at least in the logs it shows the billed duration and this only occurs after I've pushed data to the table, doesn't happen before I test the function.
Basically, I'm just testing a small function to push a UserID and Name to a DynamoDB table. I populate the params as seen below.
var UserID = toAdd['UserID']; var Name = toAdd['Name'];
var params = { Item: { 'UserID':UserID, 'Name':Name }, TableName: 'bookings2D' };
When I console log my params I'm seeing this:
dynamo.putItem(params, dynamoResultCallback);
And as you can see below, the request is at the very least being triggered.
However, when I navigate to my DB Table, and perform a table scan I receive this error:
This only occurs AFTER I run the Lambda function, if I delete and recreate the table this no longer appears. Seems like it's just something small format wise I may not be grasping.
Any help is much appreciated, any questions feel free to ask :)
Thanks
Hard refresh your browser page using CTRL + F5 or CTRL + Shift + R.
I had the same issue while creating table for phone (table name).
As a solution, I recreated the table with a different name (phone_detail).
AND IT WORKED!
You can also try to create table after a while.

Check if IndexedDB objectStore already contains key

Adding an object to an IndexedDB objectStore will fail if the key already exists. How can I check for the existence of an object with a given key – preferably synchronously (no reason for another layer of callbacks) and without pulling the object.
I know how to do get requests asynchronously via transactions, but it seems a bit of an ordeal to go through every time I want to add an object.
note Solution only has to work in Chrome (if that helps)
The best way to check existence of a key is objectStore.count(key). Which is async.
In your case, the best option is openCursor of your key. If exists, cursor will come up.
var req = objectStore.openCursor(key);
req.onsuccess = function(e) {
var cursor = e.target.result;
if (cursor) { // key already exist
cursor.update(obj);
} else { // key not exist
objectStore.add(obj)
}
};
So far none of the browsers have the sync API implemented so you're going to have to do it async. An objectStore exposes a get method which you provide it with a key and it'll return you the object (or null) that matches the key.
There's a really good tutorial on MDN that covers using IDB, and getting a record is covered too, but the inlined code is:
db.transaction("customers").objectStore("customers").get("444-44-4444").onsuccess = function(event) {
alert("Name for SSN 444-44-4444 is " + event.target.result.name);
};
If you don't want retrieve the record then you can always used the count method on an index as explained here in the spec. Based on the result of that you can either use add or put to modify the record, it'll save extracting the record if you don't need to.
A bit late for an answer, but possible it helps others. I still stumbled -as i guess- over the same problem, but it's very simple:
If you want to INSERT or UPDATE records you use objectStore.put(object) (help)
If you only want to INSERT records you use objectStore.add(object) (help)
So if you use add(object), and a record key still exists in DB, it will not overwritten and fires error 0 "ConstraintError: Key already exists in the object store".
If you use put(object), it will be overwritten.
The question is why do you want to know this? Maybe you should use another approach?
You can use auto increment, this way you don't need to check if a key exists, you will always get a unique one.
You can also use the put method instead of the add method. With the put the data will be updated if the key exists and if the key doesn't exist the data is added.
Everything depends on the reason why you want to check if something exists.

difference between key value in adressline and getId() value in Google Script

I wanted to ask what's the difference between the value in the adressline and the id I get when i use getId().
For example for one document the getId() value is:
t8K_TLQPmKzgB72pY4TblUg
while in the adressline the key is:
0Amu7sNvd2IoudDhLX1RMUVBtS3pnQjcycFk0VGJsVWc
what i figured out so far is that when you encode getId in base64 you get more or less the last part of the key in the adressline
(base64Encode(t8K_TLQPmKzgB72pY4TblUg) = dDhLX1RMUVBtS3pnQjcycFk0VGJsVWc=).
But I still don't know what 0Amu7sNvd2Iou stands for, because i have the impression that this parts also is different in older documents, therefore i can't just combine the key using all the time 0Amu7sNvd2Iou at the beginning
Why I need to know this: my scripts use the getId method but some users fill in their ids manually (they just copypaste it from the key from the adressline). The result is that when i try to compare them although they refer to the same document i can't match them like they are completly different...
thanks a lot for bringing light into this problem
edit #taras:
i can also open the document with the key and the id. It's just weird that there are kind of two different id's for one document. If for example i want to compare if a value somebody copypasted from the adressline to a document is the same as the file i have opened i won't get a true, even it is the same file
var keyFromHeadline = "0Amu7sNvd2IoudDhLX1RMUVBtS3pnQjcycFk0VGJsVWc"
var id = SpreadsheetApp.getActiveSpreadsheet.getId();
if (keyFromHeadline==id) Browser.msgBox("blabla")
Therefore i would be interested what is the reason for the two different values and how i could match them
If you need to have unique file IDs just normalize them. Everytime a user enters an ID manually just run it trough the fileIdNormalize function:
function fileIdNormalize(id) {
if (typeof id == 'string' && id.length > 0)
return DocsList.getFileById(id).getId();
return '';
}
Just a suggestion :
Since base64Encode seems to give you a significative part of the adress url you could use a match to check if the document is the same.
Something like :
if('manually_entered_key'.match(base64Encode('the_value_obtained_by_getId')==base64Encode('the_value_obtained_by_getId')){
// consider as the same doc ...

LocalStorage with Json.stringify not persisting

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.

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.