-
Notifications
You must be signed in to change notification settings - Fork 27.5k
$parse removes object keys that begin with $ (dollar sign) #1463
Comments
Angular is stripping the $ because it is used for Angular (mostly) properties/methods and when they are converted to JSON, they're stripped because it's extraneous. Here's an idea for a solution: So, for this example, '+$oid' would be stripped down to '$oid'. Thoughts? |
Quoting might be a good solution. My question is where the quoting/dequoting would occur. I believe $http is the low level transport. From my point of view, the $ would be a more traditional way to quote it. |
Same issue here, writing a plugin for grails and mongodb, I was forced to parse/marshall json object manually to keep the '$xxx' keys in the object received/sent. As a workaround for now, you can send your JSON as a string using a standard or custom json stringifier, same for the parser as the keys would be stripped from the response as well, ex:
Still waiting for a proper fix for this issue, actually even passing an object with "$xx" keys between scopes seems to strip those keys... |
how about writing a custom serializer and replace the default one with $httpProvider.defaults.transformRequest ? current implementation:
where
|
I'm not keen on not dropping the |
@IgorMinar 👍 I think it is a small number of users that this impacts and allows for flexibility unlike service APIs such as the one mentioned above that tend to be near impossible to change. |
👍 I think mongodb and angular will be quite a common stack. With static typed languages on the serverside (where json serialization is handled by 3rd party libs) this is especially problematic, as one has to rebuild all serialization. |
+1 Would really like a solution to this!! Thanks! |
This is an issue when working with MongoDB based services that are dependent on $ prefixed object properties. The framework needs to provide an escape mechanism for this. |
I had the same problem (also using MongoDB on the backend) but it seems just manually stringifying the data/params prior to calling the $http service works, i.e.
|
Could this be documented at: http://docs.angularjs.org/api/angular.toJson, right now there's no mention that angular.toJson strips properties starting with a '$'. |
I would like to see the whitelist approach taken, this would seem the simplest solution. angular.module('myApp', ['myDirectives']).
run(['$document', '$http', function ($document, $http) {
var toJsonReplacer = function(key, value) {
var val = value;
if (/^\$+/.test(key) && key !== '$oid') {
val = undefined;
} else if (value && value.document && value.location && value.alert && value.setInterval) {
val = '$WINDOW';
} else if (value && $document === value) {
val = '$DOCUMENT';
} else if (value && value.$evalAsync && value.$watch) {
val = '$SCOPE';
}
return val;
};
angular.toJson = function(obj, pretty) {
return JSON.stringify(obj, toJsonReplacer, pretty ? ' ' : null);
};
$http.defaults.transformRequest = function(d) {
return angular.isObject(d) && !(angular.toString.apply(d) === '[object File]') ? angular.toJson(d) : d;
};
}]); |
I included in angular.toJson's description that any properties with a leading '$' character will be stripped from the result since angular uses this notation internally for services. There have been complaints of not knowing about this functionality until it breaks within their code. It would be a nice addition to avoid any confusion in the future. An example of a documentation update request is within a comment in issue angular#1463.
Hey guys, |
krishh, github issues is not the right place or manner to request individual help on this topic. email me directly from your email account, or via twitter, and update your github profile with appropriate info if you are going to be requesting help. |
+1 for a solution to work with MongoDB without doing dodgy workarounds |
Gotta give this a +1 too, one of my colleagues just spent a couple hours getting blindsided by this bug. |
+1 for this - attempting to use angular.js with mongo (very common?) is a massive pain in the rump |
+1 for this |
JSON.NET parser also uses $properties, specifically when strongly typing .NET types it uses $type. Both workarounds above work (stringify and overriding toJsonReplacer), but +1 vote for a configurable whitelist. |
Sending string instead of JSON is not the solution. BIGGEST BUG, by not allowing something in JSON |
+1 |
+1 Im using mongodb. Im going to change my server code. Not ideal. |
+1 |
1 similar comment
+1 |
+1 |
+1. Not being able to use MongoDB comparison operators in a Resource is a bummer. |
+1 |
when did this get triaged as high priority? should try to get this checked in, imo. @a8m --- I don't know if that's necessarily the best way to do it, but I think it would be okay if we only removed AFAIK, |
@caitp – was just wondering that. I saw @rodyhaddad had a fix in the work for this, but it didn't implement @IgorMinar's whitelisting approach. |
@btford I was going to reply to your comment on the PR, but here's as good a place as any --- So I don't think a whitelist is necessarily the way to go, because what this means is we're saying like, So the reasons why that's problematic are pretty obvious, A) it's another list of things not in angular's control that needs to be maintained, and B) we're likely to exclude people using different toolchains on their server if we do that. So, we know that Angular has a pretty limited set of keys which it adds directly to objects (not in the prototype chain) --- My vote is to just remove own-$$-prefixed properties, or just a specific blacklist of properties which angular adds. It's the least likely to be a breaking change, and the former is the easiest to work around if it does break applications. In other words, I think @rodyhaddad's PR should be good enough for this, the whitelist is probably not a good idea |
@caitp blacklist of properties it's good idea, //current function if (typeof key === 'string' && key.charAt(0) === '$') { return val; |
|
And yes, I know that we're stripping anything with |
Even easier, request.body doesn't need replacer(stringify replacer), just stringify it :-) |
Closed via #6253. |
This commit allows additional configuration parameters to be sent for the $http request in `CouchDoc.save`. I need to do this in order to work around angular/angular.js#1463
@btford - I hope this is the right place to ask for it, but with the fix of "only stripping" |
@poths: I don't know how you are using/sendng your objects, but |
@btford - thanks a lot. I didn't know where to look for that. we had an incompatible version of angular-resource, without the custom |
…id can also be passed as €oid removed useless warning message if ref field is null
very useful for angularjs that removes all properties whose name start with $, due to issue 1463 angular/angular.js#1463 removed old angularjs workaround
If you attempt to send {'_id':{'$oid':'123'}} as an argument to a resource, the {'$oid':'123'} is removed from the http request that is sent.
This is a problem, because mongodb uses keys that start with $ as a way to serialize certain objects.
As far as I can tell there's no restriction on $ from the strings in a JSON object, so it seems the behavior of parse is wrong.
The text was updated successfully, but these errors were encountered: