Can't get $q.all to work with $resource

3,209 views
Skip to first unread message

Bogdan Sulima

unread,
Aug 2, 2012, 9:32:08 AM8/2/12
to ang...@googlegroups.com
Hello angularjs experts :)

my code makes some server calls with $resource. 

I try to synchronize calls with $q.all(....).then(....).

Seems to me, that correct value array with resolved promises is passed to the callback called by "then", but i can't access the data.
If i print values into the console, i can see correct data. But when i access it with value[index] - i still see an empty promise object.

I have build a http://jsfiddle.net/bonya/6ajEn/ with a test which illustrates my problem.

Need some help to understand what is happening.

Regards,

Bogdan Sulima.

Pawel Kozlowski

unread,
Aug 3, 2012, 4:45:52 PM8/3/12
to ang...@googlegroups.com
Hi Bogdan!

Your example is super-interesting, I didn't know that you can combine
$resource promises like this, I thought it was only possible with
$http promises... But since $resource is using $http behind the scene
it is kind of obvious... Sometimes things are just in front of you yet
you can't see them...

Anyway, this jsFiddle works: http://jsfiddle.net/6ajEn/4/ but your
original jsFiddle gives me headache... I'm kind of guessing here but I
presume that it has something to do with timing, looks like
expectations are executed before a joined promise callback is
executed... So it is probably more jasmine + $q combination problem
than a $q issue.

Need to understand this one, maybe you with my working example you
will be able to come up with a plausible theory :-) Any async /
jasmine gurus, please help :-)

Cheers,
Pawel
> --
> You received this message because you are subscribed to the Google Groups
> "AngularJS" group.
> To post to this group, send email to ang...@googlegroups.com.
> To unsubscribe from this group, send email to
> angular+u...@googlegroups.com.
> Visit this group at http://groups.google.com/group/angular?hl=en.
>
>

Kai Groner

unread,
Aug 4, 2012, 2:14:02 PM8/4/12
to ang...@googlegroups.com
The problem here is that $resource doesn't return promises.  $q.all() and $q.when() treats non-promises as resolved promises, so your callback will be called before the resource is retrieved.

The resource methods have a callback parameter which can be used to process the resource after it is retrieved.  This API was created before $q was a part of Angular.  A $resource rewrite might change this.


Jasmine has a couple of functions runs() and waitsFor() that can be used to set up and poll for changes.


Kai

Pawel Kozlowski

unread,
Aug 4, 2012, 2:45:24 PM8/4/12
to ang...@googlegroups.com
hi!

On Sat, Aug 4, 2012 at 8:14 PM, Kai Groner <k...@gronr.com> wrote:
> The problem here is that $resource doesn't return promises. $q.all() and
> $q.when() treats non-promises as resolved promises, so your callback will be
> called before the resource is retrieved.

Hmm, I'm starting to get confused... Before I saw Bogdan's example I
was 99,99% sure that $resource doesn't return promises but rather
regular JS objects. And looking at
https://github.com/angular/angular.js/blob/master/src/ngResource/resource.js
it seems like Resources are _not_ promises.
But then again, when I saw Bogdan's example it looked like you can can
combine promises... but didn't realize that you can pass regular
objects to $q.all (I was persuaded that you need to wrap them with
$q.when first).

Now, given that you _can_ pass non-promises to $q.all I've got another
puzzle: http://jsfiddle.net/pkozlowski_opensource/NvMSs/

I would assume that non-promise objects will be treated as promises
that resolve immediately so the above fiddle should display an array
of 2 elements... but no luck here...

I guess it just shows that I'm seriously confused here... Any pointers
would be highly appreciated...

Cheers,
Pawel

Kai Groner

unread,
Aug 4, 2012, 3:33:30 PM8/4/12
to ang...@googlegroups.com

You just need to put [] around the arguments to $q.all() and it will work.

Kai

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.

Pawel Kozlowski

unread,
Aug 4, 2012, 3:45:29 PM8/4/12
to ang...@googlegroups.com
Key,

On Sat, Aug 4, 2012 at 9:33 PM, Kai Groner <k...@gronr.com> wrote:
> You just need to put [] around the arguments to $q.all() and it will work.

Thank you so much for your help! I was starting to seriously doubt in
my ability to understand $q :-)
For the record, here is the working jsFiddle:
http://jsfiddle.net/pkozlowski_opensource/NvMSs/3/

Now the remaining mystery is Bogdan's example...

Cheers,
Pawel

Pawel Kozlowski

unread,
Aug 4, 2012, 4:12:59 PM8/4/12
to ang...@googlegroups.com
Hi Bogdan!

Kai was right, $resource returns regular JS object, not promises so
the $q.all(...).then(...) will get executed before $http's flush. What
you will get are "placeholders" for resources, not resources
themselves! I guess we all got confused by console.log() but it looks
like log will get updated when the $resource object gets filled in
with values from $http.

This fiddles show better what is going on here:
http://jsfiddle.net/pkozlowski_opensource/w4YZu/1/

This was a tough one, I must admit. But at least I've learned tons,
thnx for asking this question :-)

And huge thank you to Kai and Witold for thier help!

Cheers,
Pawel

On Thu, Aug 2, 2012 at 3:32 PM, Bogdan Sulima <bogdan...@gmail.com> wrote:

Bogdan Sulima

unread,
Aug 4, 2012, 7:00:09 PM8/4/12
to ang...@googlegroups.com
Hi Pawel and Kai,

thank a lot for clarification - i thought $resource returns a promise just as $http does. 

Best regards

Bogdan.
Reply all
Reply to author
Forward
0 new messages