I am trying to send data that a user puts into a textarea and text input to and API that will save the data.
Here is the function:
$scope.forward = function() {
$http({
url: 'http://appsdev.pccportal.com:8080/ecar/api/reject/' + carID,
method: "POST",
data: "comments=" + this.comments,
data: "recipient=" + this.recipient,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).
then(function(response) {
$scope.output = response.data;
})
}
What it does when it is run is it logs only the recipient and not the comments. I am guessing because I am using "data" twice and it is only recognizing the last one (in this case "recipient"). How can I pass 2 values through this to the API.
Thanks
As you said, you're overwriting the data key from the plain object you're passing to $http, send it all together:
data: { recipient: this.recipient, comments: this.comments }
pass it as an object:
data : {comments: this.comments, recipient: this recipient}
This got it working just fine:
data: 'recipient='+encodeURIComponent(this.recipient)+'&comments='+encodeURIComponent(this.comments),
Related
I have a byte array with some data in it. Now I want it to send the array in a RAW/Binary format to my embedded webserver:
var array = new Uint8Array(317);
... inserting data into array ...
$http.post('http://api/write_file', array)
.then(function(response) {
//Success
},function(response) {
//Fail..
});
Problem is that AngularJS by default sends the array as JSON - anyway to change this? I just want it to be transmitted raw!
EDIT:
I've tried to overwrite the transformRespons:
$http({
url: 'http://api/write_file',
method: 'POST',
transformResponse: function(value) {
return value; //Just return the value, without transform..
},
data: array
}).then(function(response) {
//Success
},function(response) {
//Fail
});
But no luck? it sends exactly the same JSON as before.
This is what I wrote in my factories.js:
app.factory('CustomerCompany', function($resource){
return $resource('/customer_companies/:id.json', {id: "#_id"}, {
'query':{method: 'GET', isArray:false},
'getByCustomerAccount':{
method: 'GET',
params: {customer_account_id: customer_account_id},
isArray:true,
url:'/customer_companies/get_by_account/:customer_account_id.json'
}
});
});
Because I want to fetch a list of customer_companies that belong to a particular customer_account so I need to supply a customer_account_id.
In my controllers.js,
app.controller('customerAccountEditController', function($scope, CustomerCompany) {
$scope.data = {};
var path = $location.path();
var pathSplit = path.split('/');
$scope.id = pathSplit[pathSplit.length-1];
var customer_account_id = $scope.id;
$scope.list_of_companies = [];
CustomerCompany.getByCustomerAccount({customer_account_id: customer_account_id}, function(data){
console.log(data);
//$scope.list_of_delegates.push(data);
});
});
I get a customer_account_id not defined.
Where did I go wrong?
I think you don't need to define params inside your $resource & then URL will becomes url:'/customer_companies/get_by_account/customer_account_id.json' & while calling a method you need to pass the customer_account_id, from {customer_account_id: customer_account_id} so that it would create an URL with customer_account_id=2 somtehing like that.
Service
'getByCustomerAccount':{
method: 'GET',
//params: {customer_account_id: customer_account_id}, //removed it
isArray:true,
url:'/customer_companies/get_by_account/:customer_account_id'
}
Controller
CustomerCompany.getByCustomerAccount({customer_account_id: customer_account_id + '.json'}, function(data){
console.log(data);
//$scope.list_of_delegates.push(data);
});
This worked for me.
controllers.js
CustomerCompany.getByCustomerAccount({customer_account_id: customer_account_id}, function(data){
console.log(data);
//$scope.list_of_delegates.push(data);
});
services.js
app.factory('CustomerCompany', function($resource){
return $resource('/customer_companies/:id.json', {id: "#_id"}, {
'query':{method: 'GET', isArray:false},
'getByCustomerAccount':{
method: 'GET',
isArray:false,
url:'/customer_accounts/:customer_account_id/customer_companies.json'
}
});
});
What I changed:
on the server side, I decided to use /customer_accounts/:customer_account_id/customer_companies to render the results.
I realized that the data returned is always in object form, so I changed isArray in the $resource to false.
I pass the params like the way the Pankaj Parkar suggested in the controller when I call getByCustomerAccount
params: {customer_account_id: customer_account_id},
The customer_account_id you try to assign here is not defined.
Try params: {customer_account_id: '#customer_account_id'},
I wrote a JQuery script to do a user login POST (tried to do what I have done with C# in the additional information section, see below).
After firing a POST with the JQuery code from my html page, I found the following problems:
1 - I debugged into the server side code, and I know that the POST is received by the server (in ValidateClientAuthentication() function, but not in GrantResourceOwnerCredentials() function).
2 - Also, on the server side, I could not find any sign of the username and password, that should have been posted with postdata. Whereas, with the user-side C# code, when I debugged into the server-side C# code, I could see those values in the context variable. I think, this is the whole source of problems.
3 - The JQuery code calls function getFail().
? - I would like to know, what is this JQuery code doing differently than the C# user side code below, and how do I fix it, so they do the same job?
(My guess: is that JSON.stringify and FormURLEncodedContent do something different)
JQuery/Javascript code:
function logIn() {
var postdata = JSON.stringify(
{
"username": document.getElementById("username").value,
"password": document.getElementById("password").value
});
try {
jQuery.ajax({
type: "POST",
url: "http://localhost:8080/Token",
cache: false,
data: postdata,
dataType: "json",
success: getSuccess,
error: getFail
});
} catch (e) {
alert('Error in logIn');
alert(e);
}
function getSuccess(data, textStatus, jqXHR) {
alert('getSuccess in logIn');
alert(data.Response);
};
function getFail(jqXHR, textStatus, errorThrown) {
alert('getFail in logIn');
alert(jqXHR.status); // prints 0
alert(textStatus); // prints error
alert(errorThrown); // prints empty
};
};
Server-side handling POST (C#):
public override async Task ValidateClientAuthentication(
OAuthValidateClientAuthenticationContext context)
{
// after this line, GrantResourceOwnerCredentials should be called, but it is not.
await Task.FromResult(context.Validated());
}
public override async Task GrantResourceOwnerCredentials(
OAuthGrantResourceOwnerCredentialsContext context)
{
var manager = context.OwinContext.GetUserManager<ApplicationUserManager>();
var user = await manager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError(
"invalid_grant", "The user name or password is incorrect.");
context.Rejected();
return;
}
// Add claims associated with this user to the ClaimsIdentity object:
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
foreach (var userClaim in user.Claims)
{
identity.AddClaim(new Claim(userClaim.ClaimType, userClaim.ClaimValue));
}
context.Validated(identity);
}
Additional information: In a C# client-side test application for my C# Owin web server, I have the following code to do the POST (works correctly):
User-side POST (C#):
//...
HttpResponseMessage response;
var pairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>( "grant_type", "password"),
new KeyValuePair<string, string>( "username", userName ),
new KeyValuePair<string, string> ( "password", password )
};
var content = new FormUrlEncodedContent(pairs);
using (var client = new HttpClient())
{
var tokenEndpoint = new Uri(new Uri(_hostUri), "Token"); //_hostUri = http://localhost:8080/Token
response = await client.PostAsync(tokenEndpoint, content);
}
//...
Unfortunately, dataType controls what jQuery expects the returned data to be, not what data is. To set the content type of the request data (data), you use contentType: "json" instead. (More in the documentation.)
var postdata = JSON.stringify(
{
"username": document.getElementById("username").value,
"password": document.getElementById("password").value
});
jQuery.ajax({
type: "POST",
url: "http://localhost:8080/Token",
cache: false,
data: postdata,
dataType: "json",
contentType: "json", // <=== Added
success: getSuccess,
error: getFail
});
If you weren't trying to send JSON, but instead wanted to send the usual URI-encoded form data, you wouldn't use JSON.stringify at all and would just give the object to jQuery's ajax directly; jQuery will then create the URI-encoded form.
try {
jQuery.ajax({
type: "POST",
url: "http://localhost:8080/Token",
cache: false,
data: {
"username": document.getElementById("username").value,
"password": document.getElementById("password").value
},
dataType: "json",
success: getSuccess,
error: getFail
});
// ...
To add to T.J.'s answer just a bit, another reason that sending JSON to the /token endpoint didn't work is simply that it does not support JSON.
Even if you set $.ajax's contentType option to application/json, like you would to send JSON data to MVC or Web API, /token won't accept that payload. It only supports form URLencoded pairs (e.g. username=dave&password=hunter2). $.ajax does that encoding for you automatically if you pass an object to its data option, like your postdata variable if it hadn't been JSON stringified.
Also, you must remember to include the grant_type=password parameter along with your request (as your PostAsync() code does). The /token endpoint will respond with an "invalid grant type" error otherwise, even if the username and password are actually correct.
You should use jquery's $.param to urlencode the data when sending the form data . AngularJs' $http method currently does not do this.
Like
var loginData = {
grant_type: 'password',
username: $scope.loginForm.email,
password: $scope.loginForm.password
};
$auth.submitLogin($.param(loginData))
.then(function (resp) {
alert("Login Success"); // handle success response
})
.catch(function (resp) {
alert("Login Failed"); // handle error response
});
Since angularjs 1.4 this is pretty trivial with the $httpParamSerializerJQLike:
.controller('myCtrl', function($http, $httpParamSerializerJQLike) {
$http({
method: 'POST',
url: baseUrl,
data: $httpParamSerializerJQLike({
"user":{
"email":"wahxxx#gmail.com",
"password":"123456"
}
}),
headers:
'Content-Type': 'application/x-www-form-urlencoded'
})
})
I have a couchDB database called "guestbook". I first used the code below to add the a user to the "_users" database:
$scope.submit = function(){
var url = "https://sub.iriscouch.com/_users/org.couchdb.user:" + $scope.name;
console.log(url);
$http({
url: url,
method: "PUT",
data: {name : $scope.name,
password: $scope.pass,
roles: [],
type: "user"
},
withCredentials: true,
headers: {"Authorization": auth_hash(adminUsername, adminPass)}
})
.success(function(data, status, headers, config){
console.log(headers);
console.log(config);
});
}
Once the user was added to _users I used Futon to add that user as member to my "guestbook" _security document.
After that I tried to used that username and password (that was added as a member to "guestbook" _security) to get all the documents in the "guestbook" database. See code below:
$scope.login = function(){
var url = "https://sub.iriscouch.com/guestbook/_all_docs";
$http({
url: url,
method: 'GET',
params: {
include_docs: true,
},
withCredentials: true,
headers: {"Authorization": auth_hash($scope.uname, $scope.upass)}
})
.success(function(data, status, headers, config){
$scope.book = data.rows;
console.log($scope.book);
});
}
function auth_hash(username, password)
{
return "Basic" +btoa(username + ":" + password);
}
But everytime I tired access the "_all_docs" I get a 401 unauthorised error. The username I am using to access has been added as a member into the _security documents of the guestbook database.
Can anyone help. What am I doing wrong.
Do you have added the user name w/o the org.couchdb.user prefix to the _security object?
I can easily understand your code but didn't see a obviously mistake. I would recommend you test your API calls with Postman (Chrome App) or similar to know whether the problem is client- or server-side caused.
401 indicates Couch is unable to log in your user rather than it's not allowing them access to the database.
Might be a copy/paste error in writing the code example, but it looks like your line:
return "Basic" +btoa(username + ":" + password);
Is missing a space between Basic and your hash in the returned string:
return "Basic " +btoa(username + ":" + password);
This will mean that your Authorization header isn't correct.
However, your first code block appears to use the same function successfully, so I'm clutching at straws.
I'm using angular to save new data on the database, I take the data from my inputs, put it in a object and I convert it to a Json, I send it by POST, but my JSON gets cut off and I have no clue why is it happening.
var myJson = angular.toJson(myObject);
$http({
method: 'POST',
url: 'http://url/file.php',
data: {
'data': myJson
}
})
.success(function (data){
console.log(data);
})
My file.php has a var_dump($_POST) in it, and it shows that:
[
{
"uuid":"56456456456456456456465456"
},
{
"store_name":"",
"store_email":"",
"store_facebook":"",
"contact_name":"John Doe",
"contact_email":"email#email.com",
"contact_facebook":"http://localho
Angular's http post method sends whatever data it is passed to. You should check your generated json data after
var myJson = angular.toJson(myObject); using console.log(myJson);
and that itself must be cut off.