I can't find a solution to send a PUT request data as Form Data in AngularJs.
Here's my code :
services.factory('appsInfoFactory', ['$http', function ($http) {
var apps = {};
var callPut = function (url, data, callback) {
var headers = {'Content-Type': 'application/x-www-form-urlencoded'},
User = 'aaaa',
Secret = 'dummysecret',
param = 'User=' + User + "&Secret=" + Secret;
$http.put(url + "?" + param, data, headers).success(callback);
};
apps.registerApp = function (appName, data, callback) {
callPut("/apps/" + appName, data, callback);
};
return apps;
}]);
$scope.addApps = function (Name, Repo, Root, Email, Internal, NonAtlantis) {
var User = 'aaaa',
Secret = 'dummysecret',
data = JSON.stringify({Name, Repo, Root, Email, Internal, NonAtlantis, User, Secret});
console.log(data);
appsInfoFactory.registerApp(name, data, function (val) {
console.log(val);
});
}
But it sends data as Request Payload and I want to send it as Form Data as per my backend code's requirement.
Thanks for any help.
Take a look at last line in the function callPut.
It should be like this :-
$http.put(url + "?" + param, data, {'headers': headers}).success(callback);
Last param to $http.PUT method is a config object in which it will be expecting a key as "headers" so try passing it as an object.
and I will suggest to make var config = {'headers':headers}
and then pass this config object to PUT.
$http.put(url + "?" + param, data, config).success(callback);
Related
I'm trying to pass some URL params from a react component to a database query in a separate file. Here's a breakdown of what I'm trying to do:
TL;DR: the api request doesn't seem to have the category and city fields defined when I try to query the database.
1) Grab search params from a search form component
<Link to={"tours"+"/" + this.state.category + "/" + this.state.city} >
2) User clicks search, gets redirected to search results component. Once they are redirected, this function gets called. As I expect, the props are printing with the params from the search form.
componentDidMount: function() {
// console.log(this.props.route);
console.log(this.props.params.category);
console.log(this.props.params.city);
var category = this.props.params.category;
var city = this.props.params.city;
helpers.viewTours(
{
cat: category,
cit: city
}
).then(function(response){
var tours = response.data.length ? response.data[0].tour_title : 0;
console.log("RESPONSE " + response);
console.log("RESPONSE LENGTH " + response.data.length);
console.log("RESULTS ", tours);
//this.setState({trekList: response});
})
},
3) Using a wrapper function (helpers.viewTours) I want to pass those params from the search form into a database query
viewTours: function(searchParams){
console.log("search params " + searchParams);
return axios.get("/tours/search", searchParams);
},
4) This method gets called, but the params are undefined
router.get("/search", function(req, res){
var category = req.body.cat;
var city = req.body.cit;
console.log("tours cat " + category);
console.log("tours cit " + city);
Tour.find({}, function(error, doc) {
// Send any errors to the browser
if (error) {
res.send(error);
}
// Or send the doc to the browser
else {
res.send(doc);
//return doc;
}
});
});
Thanks,
According to axios documentation, axios.get(url, [config]) where config can be to send data with request, e.g. params field or data field. data field is not valid for GET request.
You can try the following to send params to backend.
viewTours: function(searchParams){
console.log("search params " + searchParams);
return axios.get("/tours/search", { params: searchParams });
},
and on server side, use req.params to fetch params from url.
router.get("/search", function(req, res){
var category = req.params.cat;
var city = req.params.city;
// rest of code
})
This is my first question, excuse my english.
I'm working with angular and I'm using http.post for all (get and post info). And how this is wrong, I'd start to use http.get for request the record from Database.
I'm using this:
$http.get("empresa.php",{params:{id:-1,action:"get"}})
I expect receive something like this:
empresa.php?id=-1&action=get
But not work, because send this:
empresa.php?query=%7B%22id%22:-1,%22action%22:%22get%22%7D
Could you help me?
query is not so I'expect to be.
I'm using Angularjs 1.5.8
EDITION
Te factory is this:
app.factory("Data", ['$http',
function($http, ) { // This service connects to our REST API
var serviceBase = 'service/';
var obj = {};
obj.get = function(q,p) {
console.log(p);
return $http.get(serviceBase + q + ".php",{params:p}).then(function (results) {
return results.data;
});
};
obj.post = function(q, object) {
return $http.post(serviceBase + q + ".php", object).then(function(results) {
return results.data;
});
};
obj.put = function(q, object) {
return $http.put(serviceBase + q + ".php", object).then(function(results) {
return results.data;
});
};
obj.delete = function(q) {
return $http.delete(serviceBase + q + ".php").then(function(results) {
return results.data;
});
};
return obj;
}
]);
for POST work fine, but for GET doesn't work :(
New Edit
Here you can see how is that I have the code, how use and the response
Edit - Finalized
At the end, I resolved using $httpParamSerializer to serialize the json object and put it directly on call to empresa.php
Thanks to all for the help!!!
Use $httpParamSerializer to build the url query for you.
var params = {id:-1,action:"get"};
var query = $httpParamSerializer(params);
$http.get("empresa.php?" + query);
Try not using the $http.get shortcut method.
$http({
url: "empresa.php",
method: "GET",
params: {id:-1, action:"get"}
});
Or else you can create the url yourself.
$http.get('empresa.php?id=' + -1 + '&action=' + 'get');
I have a search method for domains that returns whether or not it can be registered. I am having trouble accessing the 'status' string in the returned JSON body.
Here is my AngularJS code for accessing the API:
hosting.searchDomain = function() {
var domain = hosting.domain;
var tld = hosting.tld;
var url = apUrl + 'api/domains/available.json?auth-userid='+ resellerId +'&api-key='+ key +'&domain-name='+ domain +'&tlds='+ tld +'';
$http({
method: 'GET',
url: url,
}).then(function successCallback(response) {
var data = response.data;
console.log(data);
hosting.searchResults = data;
}, function errorCallback(response) {
console.log('Eror: ', response);
});
}
And this returns something like this when you search mydomains.com:
{"mydomains.com":{"status":"regthroughothers","classkey":"domcno"}}
I don't understand how I would access the status string?
Try:
console.log(data["mydomains.com"].status);
See it working here:
https://jsfiddle.net/n6jqbcp9/
First, convert the JSON to a JavaScript object.
data = JSON.parse(data);
Access the property status:
status = data["mydomains.com"]["status"]
The API i am using returns header "Content-range" for lists :
Request : GET /users
Response contains : Content-Range: 0-49/1337
What is the correct way to generalize the retrieval (and parsing) of this header value with Restangular ?
Do i have to make my own function ?
Is there a existing method that can "catch" every response, check if the header is there and then append the parsed values (i.e : limit, range, total_count, page number) to Restangular returned object ?
Restangular has addresponseinterceptor for catching responses. You can catch your response there and get response.headers.
You should return a restangularized element in the interceptor otherwise you cannot get any data in your controllers or services...
So an example can be like this...
RestangularProvider.addResponseInterceptor(function (data, operation, what, url, response, deferred) {
var data = response.data;
var contentRange = response.headers("Content-Range");
if (contentRange) {
data.limit = contentRange.limit;
}
return data;
});
As you see you can add Restangular response interceptor on any angular config blog by injection RestangularProvider
After a few iterations on #wickY26 solution here is a technique that worked well for me :
Prerequisite
As mentioned in the question the API response contains this header :
Content-Range: 0-9/150
Which mean : The returned list will start at the 1st element (starting at 0) until the 9th on a total of 150.
On the other side the request has to include a "range=x-y" :
https://api.myapp.com/contents/?range=10-20
Code below will only work inside those contraints.
First step
Make Restangular grab all incoming responses from API. If we have a "Content-Range" header then append a pagination object with all important informations regarding pagination (from, to, total, numPage, currentPage) :
angular.module('myapp')
.config(dataConfigResponse);
dataConfigResponse.$inject = ['RestangularProvider'];
function dataConfigResponse(RestangularProvider) {
RestangularProvider.addResponseInterceptor(function (data, operation, what, url, response, deferred) {
var responseData = response.data;
var contentRange = response.headers('Content-Range');
if (contentRange) {
var rangeFields = contentRange.split(/\s|-|\//);
var paginationFrom = parseInt(rangeFields[0]) + 1;
var paginationTo = parseInt(rangeFields[1]) + 1;
var paginationTotal = parseInt(rangeFields[2]);
var paginationSubTotal = parseInt(paginationTo - paginationFrom);
responseData.pagination = {
from: paginationFrom,
to: paginationTo,
total: paginationTotal,
numPages: Math.ceil(paginationTotal / paginationSubTotal),
currentPage: Math.ceil(paginationFrom / paginationSubTotal)
};
}
return responseData;
});
}
Second step
Make Restangular intercept all outgoing requests to the API. When the action is a getList we append "?range=10-20" to the next query
angular.module('myapp')
.config(dataConfigRequest);
dataConfigRequest.$inject = ['RestangularProvider'];
function dataConfigRequest(RestangularProvider) {
RestangularProvider.addFullRequestInterceptor(function (element, operation, what, url, headers, params, httpConfig) {
if (operation === 'getList') {
if (Object.keys(params).length) {
params.range = ((params._page - 1) * params._perPage) + '-' + (params._page * params._perPage - 1);
delete params._page;
delete params._perPage;
}
}
});
}
Third step
Now the controller which is displaying the list.
function dashboardContentListCtrl($scope, dataService) {
// Pagination starting values
$scope.maxSize = 6;
$scope.currentPage = 1;
$scope.limit = 20;
$scope.pageChanged = function () {
$scope.params = {_page: $scope.currentPage, _perPage: $scope.limit};
dataService.getAllContents($scope.params).then(function (contents) {
$scope.pagination = contents.pagination;
$scope.contents = contents.plain();
}).catch(function () {
$scope.contents = [];
});
};
$scope.pageChanged();
On my app the pagination view component is angular-ui pagination directive, looking like this :
<pagination class="pagination-sm"
boundary-links="true"
ng-hide="pagination.total < limit"
total-items="pagination.total"
items-per-page="limit"
ng-model="currentPage"
max-size="maxSize"
rotate="false"
ng-change="pageChanged()"></pagination>
I have the following service in my Angular App:
myAngularApp.factory('myFactory', function($resource, HOST){
return{
getThings: function(userId, userToken){
var connection = $resource(HOST + '/user/mypost/', {'Userid': userId, 'UserToken': userToken, 'Type': 'Read'}, {
save: {
method: 'POST'
}
});
var results = connection.save();
results.$promise.then(function(data){
results = data;
});
return results;
}
}
});
In one of my controllers, I call the above factory and its function using
myFactory.getThings($scope.someId, $scope.someToken);
When I look at the Network pane in developer tools, the POST request is sent with the correct query string parameters, but the URL is appended with the same parameters (a la GET request). How do I stop the parameters from being appended to my URL?
Try passing your parameters directly to your save() function and remove them from the URL parameters argument in your $resource constructor:
var connection = $resource(HOST + '/user/mypost/', {}, {save: {method: 'POST'}});
var params = {'Userid': userId, 'UserToken': userToken, 'Type': 'Read'};
var results = connection.save(params);