Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Change what is contained in the result of a resolved $resource promise  #14460

Closed
@gaultier

Description

@gaultier

Do you want to request a feature or report a bug?
Feature request.

What is the current behavior?
The result of a resolved promise from $resource is an object (if isArray: false) containing the actual results returned over http, as well as custom keys such as $resolved and $$state.
This can cause problems when iterating over the response.
In my case, the actual response is an object whose keys are strings and values are objects (it is a dictionary of objects). It looks like:

{'joe': {id: 1, name: 'joe'}, 'jim': {id: 2, name: 'jim'}}

But when then-callback is called, it is actually passed:
{'joe': {id: 1, name: 'joe'}, 'jim': {id: 2, name: 'jim'}, $resolved: true, $$state: ...}

Which can be problematic/surprising. Consider the following code:

promise.then(function(result) {
    angular.forEach(result, function(value, key) {
      value.foo = 'foo';
    });
  });

which is a simplified version of real production code. This will run perfectly in non-strict mode on all browsers. But in strict mode, this will (in some browsers like Chrome) cause an exception:

Cannot create property 'foo' on boolean 'true'".

Because the pair ($resolved, true) will be iterated over and we will try to basically do true.foo = 'foo'. It is surprising/unclear to the developer.

See the ticket I reported on Chromium bug tracker: https://bugs.chromium.org/p/v8/issues/detail?id=4929
It appears that in strict mode, this exception should trigger. Some browsers (like Firefox 44) are not compliant on this point.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar (template: http://plnkr.co/edit/tpl:yBpEi4).

Here is a plunkr reproducing the situation:
http://plnkr.co/edit/cKjfdYu2dLGxNOkfGHaF?p=preview

It passes on Firefox 44, IE11, Edge, and breaks with Chrome 50. It should break with Firefox 48 because it seems they made some fixes to comply more closely with the spec.
Tested on Linux and Windows.

I used the $q API to simulate $resource because I did not have an open API at hand, but it should be equivalent.

What is the expected behavior?
I suggest that either no custom key/value pair is inserted in the result object passed to the then-callback, or that it is not iterated over with angular.forEach.

What is the motivation / use case for changing the behavior?
Different behavior with non-strict/strict mode, and in different browsers, especially in the light of recent changes in major browsers like Firefox. I expect some production code in some apps to break because of this. Especially with the typescript compiler adding use strict in the build files since 1.8.

Which versions of Angular, and which browser / OS are affected by this issue? Did this work in previous versions of Angular? Please also test with the latest stable and snapshot (https://code.angularjs.org/snapshot/) versions.
Tested on 1.5.3.

Other information (e.g. stacktraces, related issues, suggestions how to fix)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions