uncopenweb/torongo

New item is invalid after first save()

Closed this issue · 10 comments

  1. db = uow.data.getDatabase( ... );
  2. var item = newItem({...})
  3. db.isItem(item) // true
  4. db.save()
  5. Save reports onComplete.
  6. db.isItem(item) // false now, why?
  7. deleteItem(item)
  8. db.save() // neither onComplete nor onError fire

Looks like an item is "bad" after its initial save. I bet if I refetch it, it'll be different somehow and a valid item. _id vs __id or something?

Item after creation:

__clientId: "crud-1784ad8bc9-def2ea11e704358be62971c7f3eca8e01c17e2ba$/data/catalog/testing9/a7ac15d1@client"
__id: "/data/catalog/testing9/4cb26a992f8a551d07000039"
__isDirty: true
foo: "bar"

Item retrieved using fetch:

__id: "crud-1784ad8bb0-18687f42642ea9f763c74f173d4893b1f217e7a4$/data/catalog/testing9/4cb26a992f8a551d0700…"
__parent: Array (1)
  0: Object
  length: 1
__proto__: Array
_id: "4cb26a992f8a551d07000039"
_owner: "parente@gmail.com"
foo: "bar"

Definitely differences here. Not sure what the parent ref is all about. All I did for newItem was pass {foo : 'bar'} to create a brand new collection. Why is the record set as a parent of itself?

fixed.

I pulled the latest torongo and uow and did the following:

  1. Opened the database editor.
  2. Opened the catalog:rolodex collection.
  3. Created a row and entered a valid first and last name.
  4. Watched the XHR succeed with proper info.
  5. Double clicked the first name in the row and changed it. (This is an update to an existing item because the grid hasn't refreshed yet.)
  6. Hit enter to save the change. Nothing happens. No XHR traffic.
  7. Click Refresh or the grid column header. This causes a refetch of the items. Notice the edit is not there.
  8. Now try the first name edit again. This time it succeeds.

I originally found the problem working on uow.data.touchCollection which does a newItem, save, deleteItem, save to bring a collection into existence so it shows in the UI. It too fails. Here's my logging.

> uow.data.touchCollection({database : 'catalog', collection : 'foobar1'})
Object (the item)
isItem(newItem({foo : "bar"}): true // item is valid here
Object
isItem(item) after save: false // after first save(), item is invalid
Object

The log is supposed to continue as the code does a deleteItem then another save(). In the save onComplete or onError, there's another log message that never prints. The XHR never happens because the JS thinks the item is invalid.

For more info, the items in that last log expand to:

__clientId: "/data/cdru-catalog/foobar1/3324fa9f@client"
__id: "/data/catalog/foobar1/4cb596572f8a552f7f000004"
__isDirty: true
foo: "bar"
__proto__: Object

So even after the save now, the _owner info is missing. This looks more wrong than before.

I think I may have it now. I didn't properly restore from yesterday's mistake with git.

We clearly need better unit tests than the crap I wrote since mine don't catch any of this stuff.

Your tests are a good start though. I wouldn't remove them. I did plan to add to them to test the new APIs, but I didn't grok exactly how they're setup when I looked late at night. I'll take another crack at them in the near future.

I added a test to test.js to verify when creating items that isItem returns true before and after save. I also validate presence of _owner after save.

I don't think we should be exposing the URL of a database to the MongoStore user. We do it one place currently, that is in the url field returned from fetch on a store with collection==asterisk. That URL is no longer valid because the mode is encoded into the url now. It isn't strictly necessary for there to be anything in the record besides the id. I see it being used in DatabaseEditor.js but I don't think it is needed. The collection name is the id, so you could just delete without fetching...

Appears to be fixed now.