Sending 2 objects in 1 POST request - javascript

I'm using Angular and trying to send a request (using $resource) to an external API but I have the data I need to send in 2 different objects, while I currently only send 1. The API requires user specific actions to include an auth_token with every request.
Without the auth_token, the request would look like this:
APIShop.reg(Cart.data,
function(success) {},
function(failure) {}
);
APIShop looks like this:
app.provider('APIShop', function(API_URL) {
this.$get = ['$resource', function($resource) {
var Campaign = $resource(API_URL.url + API_URL.loc + ':service/:action/', {service: '#service', action: '#action'}, {
'reg': {method:'POST', isArray: false, params: {service: 'account', action: 'order'}},
'update': {method:'PUT', isArray: false, params: {service: 'account', action: 'order'}}
});
return Campaign;
}];
});
Cart.data is an object that looks like: {country: 'US', city: 'Seattle, WA'}
but I need to also add {auth_token: '432078e36c7a42e3c6febdac95f38c1549de6218'} from the User object in the same request. The immediate solution would probably be to add the auth_token field to the Cart object, but as I'm storing this data in the application in various models User, ShoppingCart, etc, I'd like to keep auth_token in the User object.
I tried doing
APIShop.reg(Cart.data, User.auth_token
function(success) {},
function(failure) {}
);
didn't expect it to work, and it didn't. The auth_token ends up showing as a Request Payload instead of Query String Parameters.
I also don't want to send something like {country: Cart.data.country, city: Cart.data.city, auth_token: '432078e36c7a42e3c6febdac95f38c1549de6218'} directly (as opposed to sending the object) as that will become a maintenance nightmare sooner or later.
How would I go about sending both pieces of information without adding the token to Cart (since it'll mean I need to add it to every object going forward), or listing all the fields of the object?

Refactor APIShop to receive an array:
APIShop.reg([Cart.data, User.auth_token],
function(success) {},
function(failure) {}
);
Or refactor it to receive a mapping object:
APIShop.reg({ data : Cart.data, auth : User.auth_token },
function(success) {},
function(failure) {}
);

Related

Axios sends an array of strings instead of an array of objects

Axios sends an array of strings instead of an array of objects. I have an array of objects that contains data about the event. I'm trying to send a request to the server via axios, but I get a array of strings insteenter image description heread of objects at the output
let data = {
title: 'Game',
subject: 'Some subject',
date: ['01/01/2021','01/01/2021'],
years: ['1970', '1970'],
address: 'None',
ages: [
{
title: 'Men',
weights: [{page: 0, title: '60'}]
}
]
};
api.Create({
params: data
}).then(function (response) {
console.log(response.data);
})
.catch(function (err) {
console.log(err);
});
api response
try to:
console.log(JSON.parse(response.data))
What you get back from the server is string. you need to parse it.
When you send data to and from a server, it is sent as a 'serialized' string, usually JSON format
That's how server responses work
It turned out to be an incorrect request. I used GET to pass the object, instead of POST, so it converts it to a string. I want to notice that there is an evil community on this site.

AngularJS + Parse API call service not constrained by userId as intended

For my app, I've created a service for Address, which allows me to manipulate Address objects for any given user. Aside from my standard CRUD functions, I need to have one function to list any address for a specified Parse.User.
services.js
.factory('Address',['$http', 'PARSE_CREDENTIALS', function ($http,PARSE_CREDENTIALS) {
return {
// constrain to User ID
getAll: function(userId) {
return $http.get('https://api.parse.com/1/classes/Address', {
headers: {
'X-Parse-Application-Id': PARSE_CREDENTIALS.APP_ID,
'X-Parse-REST-API-Key': PARSE_CREDENTIALS.REST_API_KEY,
'Content-Type' : 'application/json'
},
params: { "userId": userId }
});
},
// ...get(), edit(), add(), delete()
controllers.js
.controller('AddrCtrl', ['$scope', '$state', '$stateParams', '$rootScope', 'Address',
function($scope, $state, $stateParams, $rootScope, Address) {
Address.getAll($rootScope.user.id)
.success( function(data) {
console.log(data);
$scope.addresses = data.results;
})
}]);
In my Angular template, the view does return Address objects. But it returns all the Address objects when it should only be returning the Address objects with a corresponding userId. To clarify, the Address class has a userId pointer column. Each address only has one User.
Here is the log message that AddrCtrl returns in the console:
Object {results: Array[2]}
results: Array[2]
0: Object
firstName: "(test)"
lastName: "test"
// more unrelated properties
objectId: "yUEuFjLlzs"
updatedAt: "2014-12-02T20:17:55.608Z"
userId: Object
__type: "Pointer"
className: "_User"
objectId: "q1KADkp4i1"
I'm assuming that the issue lies somewhere in my $http.get() function. Ultimately, my questions is this: why does my params option not constrain my data.results to just the Address objects associated with one Parse.User?
Answer I am not looking for:
Return all Address objects and only save the ones matching Parse.User.current().id into $scope.
You need to use where clause to perform the query.
If the data type of userId is Pointer, you should write as following:
{"where": JSON.stringify({
"userId": {"__type":"Pointer","className":"_User","objectId":"userId"}}
)}

AngularJS $resource passes id as query parameter instead in url

I need to GET data from a rest API, with the product id part of the url (and not as query parameter).
The factory:
.factory('Products', ['$resource',
function($resource) {
return $resource('products/:productId', {
productId: '#id'
}, {
query: {
isArray: false
},
update: {
method: 'PUT'
}
});
}
])
The controller:
$scope.getProduct = function(id, from) {
$scope.product = Products.get({ id: id }, function(){
console.log($scope.product);
});
}
My url is constructed like:
/products?id=5426ced88b49d2e402402205
instead of:
/products/5426ced88b49d2e402402205
Any ideas why?
When you call Products.get() in the controller, you are not using the correct parameter name (you need to use "productId" instead of "id" based on your definition of the $resource). Try calling it like this instead:
Products.get({ productId: id })
Here is a snippet from the documentation for $resource which explains how it works:
Each key value in the parameter object is first bound to url template if present and then any excess keys are appended to the url search query after the ?.
In your case, it's not finding "id" as a parameter in the URL, so it adds that to the query string.

How to change data without reloading page with Angular and Node JS

Client data:
accounts = [
Account1 = {
name: 'Dan', phone: 1775123, role: 'Client', email: 'none'
},
Account2 = {
name: 'Messy', phone: 3564576, role: 'Client', email: 'none'
},
Account3 = {
name: 'Sasha', phone: 34231234, role: 'Client', email: 'Sania#mail.ta'
}
];
DOM:
<div ng-repeat="account in accounts" >
<table>
<tr>
<td><input type="checkbox" ng-change="Toggle(account.name)"/>{{ account.name }}</td>
</tr>
</table>
</div>
I just want to figure out what's the best way to change array data in DOM without page reloading. For instance I got some data in view using ng-repeat directive. I selected the option I needed and sent it to NodeJS -> MongoDB. Now I want to get this data in the same place without reloading my page.
It sounds like a very typical question, but I've been trying to find a solution for quite long time.
Just update the data in your controller and angular will update the dom. This is a small example of 2 way data binding which I think is what you want:
Plunker example
In the Toggle method you will put in your service that hits the db and changes the data:
$scope.Toggle = function(idx, account){
$scope.accounts[idx].name = account.name + " Edited";
//replace above with whatever updates the account, ie, businessService.updateAccount(account);
}
I'm assuming that you posted the data to the server and db using a post request (i.e. $http.post(url, data)).
In Angular, all Ajax calls have a a promise to the success method, therefore in the success method, do a get request to the server to retrieve your data i.e.:
$http.post(url, data)
.success(function(){
$http.get(url)
.success(function(data){
updateAccounts(data) // a function to update your accounts array
}
})
On the Server side, your node server should be listening for a get request to the above get url, and then it should use the callback to query the database for the accounts:
app.get(url, function(req, res){
// Query the database for accounts and send back result of query
res.send(200, accounts);
})
Hope that helps!

Angularjs resource query() result array as a property

I like the way the query() method returns an array of resources, which can be saved to the server again.
I am trying to use Angular against the Drupal RestWS module, which returns an object with several "meta" properties and a property called list where the actual data are stored. Is there please a way of telling the resource to take that array instead ?
Example : GET author.json returns :
first: "http://dgh/author?page=0"
last: "http://dgh/author?page=0"
list: [{id:1, type:author, uid:{uri:http://dgh/user/1, id:1, resource:user}, created:1367770006,…},…]
self: "http://dgh/author"
With the latest Angular version (1.1.2 or later), you can configure the resource with a transformResponse:
var MyResource = $resource(
'/author.js',
{},
{
'get': {
method: 'GET',
transformResponse: function (data) {return angular.fromJson(data).list},
isArray: true //since your list property is an array
}
}
);

Categories