My requirement is that I want to be able to send an object like {title: "test", price: undefined}
from my angular-app via $http.post to my nodejs app (to be able to delete the price key via Mongoose update in my mongoDB).
Problem:
Code extract
console.log(object)
$http.post(url, object)
- In the console, I see:
{title: "test", price: undefined}
- My request payload contains
{title: "test"}
==> Why doesn't my payload contain the full object? How can I add the price: undefined in my payload?
When HTTP request Content-Type
is application/json
and the payload object contains undefined
as some fields' value, those fields will be removed. Otherwise, server side program won't be able to parse the JSON successfully -- an error SyntaxError: Unexpected token u in JSON at position ...
will happen (the token u
is just the "u" of "undefined").
This is not an Angular specific behaviour, all HTTP requests should have this logic.
What happens in Angular's $http.post
?
In Angular, all request data will be transformed. When the data is JSON, toJSON
(which equals to angular.toJson
) will be invoked to do the job (source code):
transformRequest: [function(d) {
return isObject(d) && !isFile(d) && !isBlob(d) && !isFormData(d) ? toJson(d) : d;
}]
The toJson()
function is just a proxy to JSON.stringify
(source code):
function toJson(obj, pretty) {
if (isUndefined(obj)) return undefined;
if (!isNumber(pretty)) {
pretty = pretty ? 2 : null;
}
return JSON.stringify(obj, toJsonReplacer, pretty);
}
In JSON.stringify:
If undefined, a function, or a symbol is encountered during conversion it is either omitted (when it is found in an object) or censored to null (when it is found in an array).
It doesn't contain it because it is undefined
. Undefined vars are removed from the request. You will just have to know, server-side that if the variable is not included, that you should delete it. Typically you want to use the PUT
verb for updating a record, vs POST
for creating a new record.
You could send an empty string or a boolean, or something special, so that you will know in your node app to delete the key.