Welcome, guest ( Login )

WikiHome » dojo.data » Dojo Data Meetings » 2006-10-10

2006-10-10

Version 5, changed by brian 10/10/2006.   Show version history

Agenda

  • dojo.data.Read API
    1. how do we do "reference faulting" (or whatever the right term is) -- the situation where you have a giant data graph on the server, and you only have 10% loaded into data objects on the client, and when you ask a data object for some related object, it may just hand you back some other object that was already in memory, or it may initiate a request to the server to get the needed data?
    2. what does store.get(theHobbit, 'author') return?
      • an Identity
      • a reference (what's a reference?)
      • an item that is guarenteed to be available
      • an item that may or may not be available
      • a Deferred?
      • any of the above?
    3. semantics of isItem() more like isItemAvailable() (and, if so, rename it)?
      • should isItem(x) return true if x is an item Identity instead of an item?
      • should isItem(x) return true if x is an item that has been deleted? Prior to a save? After a save?
      • [adamsz: yes to all these]
      • [skinner: yes for deleted items. no if x is an item Identity, not an item. If isItem(x) returns true when x is an item Identity, that makes it impossible to use isItem() to figure out what a call to store.get() has just returned, and so you can't write GUI display code.]
      • [mitchell: How about isItem(any) for type-check, exists(item) for existence test?]
  • dojo.data.Result API
    1. how do we want to handle GUIs that page or scroll through large result sets?
      • explicitly encourage data stores like the YahooStore example?
      • explicitly discourage or forbid that type of iteration?
      • other alternatives?
    2. what does inProgress() mean?
      • forEach() loop is in progress?
      • data is loading (query has been sent, forEach() not yet called)?
      • either of the above?
      • ~[adamsz: for clarity maybe instead we should have a state member;
        • i think we need: initial, receiving, completed, error
        • compare with:
        • xmlhttprequest.readyState: 0 uninitialized, 1 open, 2 sent, 3 receiving, 4 loaded,
        • deferred.fired: -1 initial, 0 success, 1 error
        • ]~
      • [skinner: Having a state property seems like a good idea. Should the state property convey info about (a) progress loading data from the server (initial, receiving, completed), or (b) progress iterating through the forEach loop (initial, looping, completed), or (c) some combination of both? What's the name of the state property, and do we want some sort of getState() accessor method]
      • [mitchell: State member is good, for determining resultset state between store (local or remote) and JS client]
    3. signature for oncompleted callback?
      • [adamsz: oncompleted(iterator)]
      • [skinner: oncompleted(). We might consider passing an iterator to the callback method that the caller sets with setOnLoopCompleted(callback). We should not pass an iterator to the callback method that the caller sets with setOnFindCompleted(callback), since that doesn't work well with the style of access that we might want to do in paging/scrolling implementations like the YahooStore. Offering a synchronous-iterator creates a new implementation requirement that dictates that all results will be in memory at once. Synchronous looping is a nice feature to have, but we shouldn't impose the the all-results-in-memory requirement every time a find() is complete, as would be required if we automatically pass an iterator in to the oncompleted callback -- we should only impose the the all-results-in-memory requirement if the calling code explicitly asks for synchronous looping by calling a asIterator() or asArray() method. If we do have a asIterator() or asArray() method, I have a strong preference for asArray() instead of asIterator(), because looping through an array is something that every JavaScript textbook covers, whereas the iterator syntax is dojo-specific and less obvious.]
      • [mitchell: onCompleted(). We may also want to consider whether it makes sense to use "well known" topics for store or data events. Eg., dojo:data/store/yahoo1/recieving or dojo:data/store/yahoo1/valueChanged]
  • dojo.data.Write API
    1. save()
      • store.save({sync: false})?
      • store.save({sync: false, onComplete: callback});
      • always return a Deferred, or sometimes a boolean?
      • default to sync, not async?
      • [adamsz: save({sync:true}), always return Deferred (test result.fired for success) ]
    2. include methods add() and remove()
      • store.set(kermit, color, "green");
      • store.add(kermit, color, "blue");
      • store.add(kermit, color, "aqua", {at: 0});
      • store.add(kermit, color, "cyan", {after: "blue"});
      • store.remove(kermit, color, "green");
      • [adamsz: ok, but lets name them add/removeValue. And significance of order and whether duplicate values are allowed should be implementation dependent. also, clarify that removeValue removes all matching values if there are duplicates.]
      • [mitchell: +1, clarify that add with no optional 4th parm adds at end of value list, and at can be used for remove as well.]
    3. should isDirty() with no args returns whether the current transaction is dirty?
      • [adamsz: yes]
      • [skinner: Why not isDirty(store), as per the current documentation, rather than isDirty()? Or are you saying we should support isDirty() and isDirty(store), with different semantics?]
      • [mitchell: 0, could we move this to change-tracking interface?]
    4. should dojo.data.Write include (extend) dojo.data.Read?
  • add new code (where?, minor code style stuff first?)
    1. check in RemoteStore?
    2. check in mockXmlHttpRequest?
    3. move dojo.data.csv.Result out of .csv, for re-use?
      • [adamsz: yes, rename to something like SynchronousResult]
      • [mitchell: yes, assuming it's in sync with latest api]
  • wait to sign off on some APIs (Read/Result/Write) until after we have some lessons learned from trying initial implementations?
    • [mitchell: yes]

Resolutions

  • none this week

Transcript

[1:01 PM] aszs: hi brian
[1:01 PM] brian_skinner: hi aszs 
[1:01 PM] aszs: i have a (relatively) radical idea
[1:01 PM] brian_skinner: hi dmachi, tk, rcoup
[1:01 PM] brian_skinner: aszs: shoot
[1:02 PM] aszs: eliminate dojo.Result
[1:02 PM] brian_skinner: that's radical!
[1:02 PM] aszs: it fixes problems and makes things simpler
[1:02 PM] aszs: instead add
[1:02 PM] aszs: oncompleted, onnext, array, onerror keywords
[1:02 PM] aszs: to find()
[1:02 PM] aszs: var results=[];
[1:02 PM] aszs: var success = find("query", { array : results });
[1:03 PM] aszs: for simply synchronous query
[1:03 PM] brian_skinner: {array: results} is optional?
[1:03 PM] aszs: yes
[1:03 PM] aszs: instead use onnext
[1:03 PM] aszs: if u don't want all the results saved
[1:03 PM] brian_skinner: give me a second to look at the current apis and think about that
[1:03 PM] aszs: { onnext : myhandlerfunc }
[1:04 PM] aszs: i thought of this because of another problem with Result
[1:04 PM] aszs: what happens if the query is synchronous and there's an error
[1:04 PM] brian_skinner: yup, that's a problem
[1:05 PM] aszs: you don't set the onerror handler till after u get a result
[1:07 PM] brian_skinner: for the synchronous error case, couldn't you just call find() and get a result object back, where the result object knows that there was an error, and when you do result.setOnError(foo) then foo will get called?
[1:07 PM] aszs: yes
[1:07 PM] dmachi: hi everybody
[1:08 PM] aszs: but then you need to have a error handler just to find if there was one
[1:08 PM] brian_skinner: hi dmachi 
[1:08 PM] brian_skinner: aszs: yup, it's a little clumsy
[1:08 PM] aszs: its not a big deal
[1:08 PM] aszs: its just how i came to this new idea
[1:08 PM] dmachi: aszs: you could do something like deferred does in that if you add a callback after the results have alreayd been recieved it just callsback with those immediately (same in case of errback)
[1:08 PM] aszs: dmachi: yes
[1:08 PM] dmachi: (maybe?)
[1:09 PM] brian_skinner: dmachi, aszs:  i got mail from chris -- he says he's not going to be able to make it today
[1:09 PM] dmachi: i wasn't really here either, this is just and idle channel and i got a little pop from my name being mentioned :)
[1:09 PM] brian_skinner: :)
[1:10 PM] brian_skinner: aszs: how would getLength() work?
[1:10 PM] aszs: yes
[1:10 PM] aszs: maybe result could be the length or -1 on error
[1:11 PM] brian_skinner: you mean...
[1:11 PM] aszs: if its async the length could be an arg for oncompleted
[1:11 PM] brian_skinner: var length = find(query, ...)
[1:11 PM] brian_skinner: right
[1:11 PM] aszs: yes
[1:11 PM] aszs: and if array is passed
[1:11 PM] aszs: just look at the array length
[1:11 PM] brian_skinner: right
[1:12 PM] aszs: then there's cancel
[1:12 PM] aszs: it could work like io.bind
[1:13 PM] aszs: pass abort kword
[1:13 PM] aszs: that gets set to an abort function
[1:13 PM] aszs: so abort and sync would be the same as io bind
[1:14 PM] aszs: so would error and completed
[1:14 PM] brian_skinner: i've never actually used dojo.io.bind -- i'll have to go look at it to understand about abort, error, completed
[1:15 PM] brian_skinner: so, just thinking out loud,
[1:15 PM] aszs: there just callback funcs
[1:15 PM] brian_skinner: for the sync case...
[1:15 PM] brian_skinner: var store = new dojo.data.csv.CsvStore({url:"movies.csv");
[1:15 PM] brian_skinner: var results = new Array();
[1:15 PM] brian_skinner: store.find(null, {array:results});
[1:15 PM] brian_skinner: it would be nicer to do this...
[1:15 PM] brian_skinner: var store = new dojo.data.csv.CsvStore({url:"movies.csv");
[1:15 PM] aszs: yes
[1:15 PM] brian_skinner: var results = store.find();
[1:16 PM] aszs: yes that'd be nicer but we can't do that
[1:16 PM] brian_skinner: if no oncompleted, onnext, array, onerror keywords are passed, then assume we just want a simple array
[1:16 PM] brian_skinner: and return an array
[1:16 PM] aszs: good idea
[1:16 PM] aszs: if array is null assum an error
[1:16 PM] brian_skinner: right
[1:17 PM] brian_skinner: or maybe it throws an exception if there's an error, i don't know
[1:17 PM] aszs: well this makes things *much*  simpler
[1:17 PM] brian_skinner: so, what does some simple async code look like?
[1:17 PM] brian_skinner: var store = new dojo.data.csv.CsvStore({url:"movies.csv");
[1:18 PM] aszs: find("query", { onnext=myforeachfunc } )
[1:18 PM] brian_skinner: store.find(someQuery, {oncompleted: foo, onnext: bar, onerror: iggy});
[1:18 PM] aszs: well in the simple case use just need onnext
[1:19 PM] brian_skinner: yes, right
[1:19 PM] aszs: and sync=false
[1:19 PM] brian_skinner: right
[1:19 PM] aszs: or array=result and oncompleted=foo
[1:19 PM] brian_skinner: store.find(someQuery, {sync: false, oncompleted: foo, onnext: bar, onerror: iggy});
[1:20 PM] aszs: or store.find(someQuery, {sync: false, oncompleted: foo, array: result);
[1:20 PM] brian_skinner: right
[1:21 PM] brian_skinner: just off the top of your head, is it easy for you to show me an example of what abort/cancel would look like?
[1:21 PM] aszs: let me look at my RemoteStore
[1:22 PM] aszs: i use bind's abort
[1:22 PM] aszs: to implement cancel
[1:22 PM] aszs: actually i'm wrong about io.bind
[1:24 PM] aszs: they implement it this way:
[1:24 PM] aszs: kwargs  = {}
[1:24 PM] aszs: io.bind( kwargs); //funct sets kwargs.abort here
[1:24 PM] aszs: var abortfunc = kwargs.abort
[1:24 PM] aszs: but the use sees this:
[1:24 PM] aszs:                     var request = dojo.io.bind( { ... });
[1:24 PM] aszs:                     result._abortFunc = request.abort;
[1:24 PM] aszs: the user i mean
[1:26 PM] aszs: i guess we could return minimal request object if its async
[1:26 PM] aszs: or do it the former way
[1:26 PM] brian_skinner: i'm confused -- so dojo.io.bind returns a request object, and that request object has an "abort" property which points to a function?
[1:26 PM] aszs: yes
[1:27 PM] brian_skinner: and you can call that function if you want to cancel the request?
[1:27 PM] aszs: yes
[1:27 PM] brian_skinner: okay
[1:27 PM] aszs: result.abort()
[1:28 PM] brian_skinner: or we could just return a *token* representing the request...
[1:28 PM] brian_skinner: var token = store.find(someQuery, {sync: false, oncompleted: foo, onnext: bar, onerror: iggy});
[1:28 PM] brian_skinner: and then...
[1:28 PM] brian_skinner: store.abort(token);
[1:28 PM] aszs: yes
[1:29 PM] aszs: but why?
[1:29 PM] brian_skinner: which isn't as object-oriented, but it means we don't even have to start any kind of conversation about what a request object is
[1:29 PM] brian_skinner: and we don't have to have a whole new file for dojo.data.Request API
[1:30 PM] aszs:  io.bind doesn't define what the result object is
[1:30 PM] aszs: just has one
[1:30 PM] brian_skinner: and it defines a little bit about how it behaves
[1:30 PM] brian_skinner: it conforms to some API
[1:30 PM] aszs: but there no dojo.io.Result
[1:30 PM] aszs: just uses duck typing
[1:30 PM] brian_skinner: right -- the API only appears in documentation
[1:31 PM] brian_skinner: http://manual.dojotoolkit.org/io.html
[1:32 PM] brian_skinner: ...
[1:32 PM] aszs: the doc says there *is* dojo.io.request
[1:32 PM] aszs: i didn't see that
[1:32 PM] brian_skinner: http://dojotoolkit.org/api/#dojo.io.Request
[1:33 PM] aszs: its not in the source code
[1:33 PM] aszs: not a real object
[1:33 PM] aszs: just a dictionary
[1:33 PM] brian_skinner: it must be in the source code somewhere, or it wouldn't appear in the automatically generated API docs
[1:33 PM] aszs: hmmm
[1:34 PM] brian_skinner: well, we can look into that more later
[1:34 PM] aszs: its in common.js
[1:34 PM] brian_skinner: in any case, we can do something like that for abort/cancel
[1:34 PM] aszs: doesn't look like BrowerIO uses that...
[1:34 PM] aszs: yes, in any case...
[1:35 PM] aszs: well, what do u think?
[1:35 PM] brian_skinner: okay, getting rid of the dojo.data.Result certainly has some appeal
[1:36 PM] brian_skinner: and I like the simple API for getting an array
[1:36 PM] brian_skinner: make simple things simple
[1:36 PM] brian_skinner: but I don't have a strong sense one way or the other about which API is better -- with dojo.data.Result or without
[1:37 PM] brian_skinner: it'd be great to get feedback from a few more people about the idea
[1:37 PM] brian_skinner: see what Chris and Tom think
[1:37 PM] aszs: ok
[1:37 PM] brian_skinner: i'm happy to follow whatever the consensus opinion is
[1:37 PM] brian_skinner: we could add it to our next agenda
[1:38 PM] brian_skinner: or you could write up some mail and send it to dojo-dev, if you feel like it
[1:38 PM] aszs: i could send an email or add a wiki page
[1:38 PM] aszs: which do u think is better?
[1:38 PM] brian_skinner: yup, or a wiki page
[1:38 PM] brian_skinner: my sense is that people read mail more than they read the wiki
[1:38 PM] aszs: ok
[1:39 PM] aszs: so what would be the arguments for keeping Result?
[1:39 PM] brian_skinner: inertia ;-)
[1:39 PM] brian_skinner: i don't know -- i don't think I have any good arguments
[1:40 PM] aszs: ok
[1:40 PM] aszs: to clarify: so if find is sync return an array unless onnext is specified?
[1:41 PM] aszs: or return an array always if sync?
[1:41 PM] brian_skinner: although, maybe we actually are talking about keeping it, in some minimal sense -- you do still get back a result object, and you can call result.abort(), and maybe you can get state info, like result.inProgress()
[1:41 PM] brian_skinner: find should default to sync
[1:41 PM] brian_skinner: so that makes the rule be something like this
[1:41 PM] aszs: yes
[1:42 PM] brian_skinner: return an array unless onnext and/or sync:false have been specified
[1:42 PM] brian_skinner: i'm not sure whether it's "and" or "or"
[1:43 PM] brian_skinner: i guess "or"
[1:43 PM] brian_skinner: although it would be weird to specify sync:false and not provide an onnext:foo
[1:43 PM] aszs: if sync false
[1:43 PM] aszs: we can't return an array
[1:43 PM] brian_skinner: right
[1:44 PM] aszs: unless we return an empty array
[1:44 PM] brian_skinner: and there probably isn't much value in doing that
[1:44 PM] aszs: so i guess its "or"
[1:44 PM] brian_skinner: okay
[1:45 PM] aszs: so we don't really need an array kwarg
[1:46 PM] brian_skinner: maybe not
[1:46 PM] brian_skinner: it'd be great to not need that
[1:46 PM] aszs: onnext : function(item) { result.push(item) }
[1:46 PM] aszs: if we don't want the user to have to write that
[1:46 PM] aszs: we could say if onnext's value is not an function
[1:47 PM] aszs: will call object.push(item) on it
[1:47 PM] aszs: instead of invoking it
[1:47 PM] aszs: then you could just go onnext : myArray
[1:47 PM] aszs: sync : false
[1:47 PM] aszs: xhr does something like
[1:47 PM] aszs: i think
[1:47 PM] brian_skinner: hmmm...  but that's kind of weird for large result sets
[1:48 PM] aszs: yes,
[1:48 PM] aszs: so user shouldn't do that
[1:48 PM] brian_skinner: if you know you're looking at 10,000 things -- conceptially you really don't want to "push" them onto an object
[1:48 PM] aszs: ok
[1:49 PM] aszs: we could just say onnext can be either a function or an array
[1:49 PM] brian_skinner: yes, that has some appeal
[1:49 PM] brian_skinner: but
[1:49 PM] aszs: is that better?
[1:49 PM] brian_skinner: seems like if you really want an array, then you're not going to want to see the array until after the whole loop has finished anyway
[1:49 PM] aszs: yes?
[1:50 PM] brian_skinner: so what you really want is something like this...
[1:50 PM] aszs: find( { sync: false, onnext : myarray, oncompleted: myfunc })
[1:50 PM] brian_skinner: maybe 
[1:50 PM] brian_skinner: but that code would really look like this...
[1:51 PM] brian_skinner: var array = new Array();
[1:51 PM] brian_skinner: store.find( { sync: false, onnext : myarray, oncompleted: myfunc });
[1:51 PM] brian_skinner: ...
[1:51 PM] aszs: yes
[1:51 PM] brian_skinner: why should I have to create the array object?
[1:51 PM] brian_skinner: would it be better to do this...
[1:52 PM] brian_skinner: store.find( { sync:false, oncompleted: myfunc, array: true});
[1:52 PM] brian_skinner: or ...
[1:52 PM] aszs: yes
[1:52 PM] aszs: yr right
[1:53 PM] brian_skinner: store.find( { sync:false, onarrayloaded:myfunc});
[1:53 PM] aszs: and array is always true when sync = true
[1:53 PM] brian_skinner: yes
[1:53 PM] aszs: don't think we need a separate onarrayloaded
[1:53 PM] aszs: oncompleted(length, array)
[1:53 PM] aszs: array might be undefined if array : false
[1:54 PM] brian_skinner: yes
[1:54 PM] aszs: all this seems more elegant
[1:54 PM] aszs: and easier to implement stores
[1:55 PM] aszs: especially simple ones
[1:55 PM] brian_skinner: i was just thinking {onarrayloaded:myfunc} might be less confusing than {oncompleted: myfunc, array: true}, where there's some "invisible" interaction between the two parameters, myfunc and array:true, such that the params sent to myfunc are actually different depending on what array: was set to
[1:56 PM] brian_skinner: but, this is a pretty minor detail anyway
[1:56 PM] brian_skinner: ...
[1:56 PM] brian_skinner: so, should we talk about what "reference faulting", and what type of item/identity/reference you might get when you call store.get(theHobbit, "author")?
[1:56 PM] aszs: ok
[1:57 PM] brian_skinner: give me one minute...
[1:57 PM] aszs: ok... i was thinking the maybe the API doesn't distinguish
[1:57 PM] aszs: if item isn't loaded, then the store.get(item, 'foo')
[1:57 PM] aszs: would just remotely load the item if necessary
[1:58 PM] aszs: up to the implementation
[1:58 PM] brian_skinner: okay, i'm back
[1:58 PM] aszs: i mean doesn' t distinguish between items and references
[1:59 PM] brian_skinner: okay, so then store.get(item, 'foo') always returns an item (or a literal -- string, number, date, etc.)
[1:59 PM] aszs: yes
[1:59 PM] aszs: isItem(item) == true
[2:00 PM] aszs: if 'foo' returns an item
[2:00 PM] brian_skinner: and we don't make any distinction between "available items" and "not quite available items"?
[2:00 PM] aszs: hmm, i think so
[2:00 PM] aszs: isItem and isItemAvailable()
[2:00 PM] aszs: need both i think
[2:00 PM] brian_skinner: when would isItemAvailable() be false?
[2:01 PM] aszs: if it isn't loaded or has been deleted
[2:01 PM] brian_skinner: okay, let's ignore the deleted case for a second
[2:02 PM] brian_skinner: so, that API imposes a constraint on the implementations
[2:03 PM] brian_skinner: the implementation has to use the same "item" object to represent the item both before and after the item is loaded
[2:03 PM] aszs: why?
[2:03 PM] brian_skinner: var tolkein = store.get(theHobbit, "author")
[2:04 PM] brian_skinner: if (isItemAvailable(tolkein) { var name = store.get(tolkein, "name") }
[2:04 PM] aszs: isItem(item) { return item instanceof Item || item instanceof Reference; }
[2:04 PM] aszs: oh i see
[2:05 PM] brian_skinner: it's not a problem for any datastore that uses UUIDs or URLs or integers as "item" objects
[2:06 PM] brian_skinner: and also not a problem if you use a JSON-style anonymous object to represent items
[2:06 PM] aszs: well what if there's no isItemAvailable
[2:06 PM] brian_skinner: but i think it might be a problem for datastores that use XML DOM nodes to represent items
[2:06 PM] aszs: is that ok?
[2:07 PM] brian_skinner: if there's no isItemAvailable(), is that the same as saying that any item returned by store.get() is required to be available?
[2:08 PM] brian_skinner: which means store.get() may take a long time to execute, since it may go to the server?
[2:08 PM] aszs: yes or...
[2:08 PM] aszs: user catch exceptions
[2:09 PM] aszs: or change store.get() to return an error somehow
[2:09 PM] brian_skinner: you mean store.get(theHobbit, "author") could return/throw an error if theHobbit isn't an "available" item?
[2:10 PM] aszs: maybe.. ie if( store.get(the, 'authro') == ITEM_NOT_AVAILABLE) ....
[2:10 PM] aszs: or ITEM_DELETED
[2:11 PM] aszs: etc.
[2:11 PM] aszs: maybe some store would fetch automatically
[2:12 PM] aszs: or maybe that could be a flag when creating the store autofetch = true
[2:12 PM] brian_skinner: yup, that would work -- but that makes the GUI code painfully verbose -- you can't use the datastore without constantly doing if() statements to check that you really got a result back
[2:12 PM] brian_skinner: ah, I like autofetch=true
[2:12 PM] brian_skinner: and we could default to autofetch=true
[2:12 PM] brian_skinner: like defaulting to sync=true
[2:13 PM] aszs: so an arg for find? or a global flag for the store?
[2:13 PM] brian_skinner: i was thinking global flag for the store
[2:13 PM] aszs: yes, that seems better
[2:14 PM] brian_skinner: so, if autofetch=false
[2:14 PM] brian_skinner: how does that work
[2:14 PM] brian_skinner: what does the client code look like?
[2:14 PM] aszs: maybe just throws an exception
[2:14 PM] brian_skinner: if( store.get(the, 'authro') == ITEM_NOT_AVAILABLE) {
[2:14 PM] aszs: just like get is currently defined
[2:14 PM] === / Unknown command
[2:14 PM] === /what Unknown command
[2:14 PM] brian_skinner: }
[2:15 PM] aszs: then we don't need to spec it out?
[2:16 PM] brian_skinner: yup, maybe we don't need to spec it out -- I was just curious about what the code would look like in some typical example -- what does the client code do once it finds out that an item is not yet available?
[2:16 PM] aszs: call getByIdentity(item)
[2:16 PM] aszs: ?
[2:17 PM] aszs: or findById() that is
[2:17 PM] brian_skinner: but, getByIdentity() doesn't take an item as a parameter -- it only takes an Identity
[2:17 PM] brian_skinner: right, sorry, findById()
[2:17 PM] brian_skinner: findByIdentity()
[2:17 PM] aszs: well maybe it should be able to take either
[2:17 PM] aszs: don't see any harm in that
[2:17 PM] brian_skinner: so...
[2:18 PM] brian_skinner: var tolkein = store.get(theHobbit, "author")
[2:18 PM] brian_skinner: and then if items are being represented as XML DOM nodes, but tolkein hasn't been loaded?
[2:19 PM] aszs: raise an Error
[2:20 PM] aszs: i think get such continue to raise errors
[2:20 PM] brian_skinner: raise an Error if theHobbit hasn't been loaded, or raise an Error if tolkein hasn't been loaded?
[2:20 PM] aszs: theHobbit
[2:20 PM] brian_skinner: okay, i'm fine with that -- but what if tolkein hasn't been loaded?
[2:20 PM] aszs: what does that mean?
[2:21 PM] aszs: oh
[2:21 PM] aszs: you want to try to load before call get on it?
[2:22 PM] aszs: if (store.isItem(tolkien))  { tolkien = store.findById(tolkien); } //ensure its loaded
[2:22 PM] brian_skinner: should store.get(theHobbit, "author") block on a trip to the server to get tolkien?  or do we return (immediately) the Identity of tolkien, or a reference to tolkien?
[2:22 PM] aszs: no its should block
[2:22 PM] aszs: just like we agreeed last week that findbyid blocks
[2:23 PM] brian_skinner: right, so if we don't block, then what does store.get(theHobbit, "author") return
[2:23 PM] brian_skinner: either an Item or an Identity?
[2:23 PM] brian_skinner: so that you can do...
[2:23 PM] brian_skinner: if (store.isItem(tolkien)) { tolkien = store.findById(tolkien); } //ensure its loaded
[2:23 PM] aszs: no it should block
[2:23 PM] aszs: yes
[2:24 PM] brian_skinner: okay, that seems like an okay solution
[2:24 PM] aszs: yup
[2:25 PM] aszs: what to propose that on the wiki page?
[2:25 PM] brian_skinner: but then I think maybe findByIdentity() actually does belong in the dojo.data.Read API, rather than off in dojo.data.Identity, since we're now saying that another dojo.data.Read method (the get method) will sometimes return Identities
[2:26 PM] aszs: its not really returning identities
[2:26 PM] brian_skinner: it's not?
[2:26 PM] brian_skinner: var tolkein = store.get(theHobbit, "author")
[2:26 PM] brian_skinner: if (store.isItem(tolkien)) { tolkien = store.findById(tolkien); } //ensure its loaded
[2:26 PM] brian_skinner: ...
[2:27 PM] aszs: i think findById should work with items
[2:27 PM] aszs: too
[2:27 PM] brian_skinner: you mean, findByIdentity works with unavailable-items
[2:27 PM] aszs: it may or may not be an "Identity"
[2:27 PM] aszs: that up to the implementation
[2:28 PM] aszs: Identity isn't a dojo call
[2:28 PM] aszs: its just a mixin to the store
[2:28 PM] aszs: i mean...
[2:28 PM] aszs: tolkien isn't a dojo.Identity
[2:28 PM] aszs: there maybe some implementation defined Identity object that gets returned
[2:29 PM] aszs: but as long as isItem(tolkien) return true
[2:29 PM] aszs: it doesn't make a difference to the api
[2:31 PM] brian_skinner: hmm... i think my brain is starting to fade -- i'm not crazy about having both (a) the notion of items vs. identities and also (b) the notion of available items vs. not-yet-available items -- i'd rather have just one or the other, but i'm too fried to articulate options/problems
[2:32 PM] aszs: ok
[2:32 PM] aszs: let's wait till next week
[2:33 PM] brian_skinner: okay, sorry i'm not sharper todya
[2:33 PM] brian_skinner: today
[2:33 PM] aszs: no problem
[2:33 PM] brian_skinner: so, other stuff for now?
[2:33 PM] brian_skinner: or adjourn until next week?
[2:33 PM] aszs: i think we're good for today
[2:33 PM] aszs: yes
[2:34 PM] brian_skinner: okay, col
[2:34 PM] brian_skinner: cool
[2:34 PM] aszs: i'll write an email about the REsult
[2:34 PM] aszs: changes
[2:34 PM] brian_skinner: sounds good, thanks

Attachments (0)

  File By Size Attached Ver.