I'm refactoring my angular code from using $http to ngResource.
I used to have code like this in my service:
svc.login = function(username, password) {
return $http.post(apiEndpoint + 'authenticate', {
username: username,
password: password
})
.then(function(val) {
console.log("user token:", val.data);
svc.token = val.data;
});
};
The user token printed will be a jwt token. Now I try to refactor the code to something like this:
svc.login = function(username, password) {
svc.authenticateApi().post(apiEndpoint + 'authenticate', {
username: username,
password: password
},
function(val) {
console.log("user token:", val);
svc.token = val;
},
function(res) {
console.log("error:", res.status + " " + res.statusText);
});
};
However, it doesn't work because the parameter val passed to the first callback is no longer the token itself but a object which contains a string array like this:
What's the standard way to handle data returned from post method? (in this case post is defined the same as save on this resource)
I think the issue comes from transformRespose
transformResponse – {function(data,
headersGetter)|Array.} – transform
function or an array of such functions. The transform function takes
the http response body and headers and returns its transformed
(typically deserialized) version. By default, transformResponse will
contain one function that checks if the response looks like a JSON
string and deserializes it using angular.fromJson. To prevent this
behavior, set transformResponse to an empty array: transformResponse:
[]
try transforming your response into a json:
transformResponse: function (data) {
return { token: angular.fromJson(data) }
Related
I am facing the issue that I cannot fully undertsand how to call a function that uses a callback and get the results of the callback returned in a way where the data from the response becomes available to a Vue application.
async loginUser(username, password) {
AWS.config.update({region : region});
const payload = {
AuthFlow: "USER_PASSWORD_AUTH",
ClientId: clientId,
AuthParameters : {
USERNAME: username,
PASSWORD: password
}
}
var cognito = new AWS.CognitoIdentityServiceProvider();
return cognito.initiateAuth(payload, function(err,data) {
if (err) {
alert("Error: " + err);
return null;
}
else {
tokenData = data["AuthenticationResult"];
console.log(tokenData);
return tokenData;
}
})
}
I want the tokenData to be what is returned when calling loginUser, but no matter what I try to do the data from the cognito.initiateAuth, that should be used in my application to validate a sign in, will just be null and not usable.
Hope you guys can help!
Thanks
I tried different solutions using promises, async/await, while loops trying to wait for the response to contain data, but nothing seems to work. I can see the data being printed correctly in the callback, but how do it get this data to pass on to the return of loginUser.
I am trying to use the requestjs package to post data and wait for a response. But I the body response is always undefined.
var request = require('request');
request({
method: "POST",
baseUrl: "https://255.255.255",
uri: "/login",
form: {
username: "username",
password: "password",
autologin: "true"}},
function(body, msg, err){
console.log(body); console.log(msg);
})
Edit: Again, the undefined body was caused by a privacy policy.
The format for the callback is (err,response,body); maybe that is why you are getting a empty body and response.
You can refer here for details.
I think you are getting confused with Promise and non-promise request package. As per your example, $ajax returns Promiseified response and you directly get the data from the response of the ajax request. You are expecting that request package should also give you data directly, which is not correct.
Actually, you can solve your issue in two ways:
Sol. 1:
Use proper callback function arguments and you must get data in the third argument of the callback function. Such as:
var request = require('request');
request({
method: "POST",
baseUrl: "https://255.255.255",
uri: "/login",
form: {
username: "username",
password: "password",
autologin: "true"
}
},
function (error, httpResponse, body) {
if (error) {
console.error(error);
}
console.log(httpResponse.statusCode);
console.log(body);
});
Sol. 2:
Use request-promise NPM package (download it from here) and get pomisified response. For example:
var request = require('request-promise');
const getData = async () => {
return new Promise((resolve, reject) => {
const options = {
method: "POST",
baseUrl: "https://255.255.255",
uri: "/login",
form: {
username: "username",
password: "password",
autologin: "true",
resolveWithFullResponse: true, // Returns full response. To get only data don't use this property or mark it false.
}
};
// Get whole Response object.
const response = await request(options);
// Returns the Promise.Resolve or Reject based on response.
if (response.statusCode < 200 || response.statusCode > 300) {
const errorMsg = 'Error occurred while POSTing the request. Got status: ' + response.status;
console.error(errorMsg);
// Reject the promise. Should be caught.
return reject(errorMsg);
}
const responseBody = response.body;
console.log(responseBody);
// Return the response.
return resolve(responseBody);
})
}
Above implementation will return a promise for the method getData() being called.
NOTE: The statement const response = await request(options); will return whole response object if resolveWithFullResponse: true, is used in the options JSON object. If you need only response body or data don't mention resolveWithFullResponse property in the options or assign value false to it. By default the value of resolveWithFullResponse is false.
i got a frisby function
createPOST = function () {
return frisby.post(url, {
body: qs.stringify({
username: data.user,
password: data.password
}),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then((resp) => {
let respJson = resp.json;
return respJson;
}, (error) => {
console.error("Error:: " + error);
throw error;
});
}
and second function
getRespJson = function () {
createToken().then(function (value) {
console.log("resp::"+value);
});
}
im trying to retrieve this json response in another function, but not able to using frisby. no log is even displaying
If your data coming in the body(that you are expecting) or anywhere, simply store into other variable and then by nested way you able to use it. if you have multiple nested body then in that situation you also able to use it.
I'm using the same with that workaround.
or try to use it by storing that into another file.
Thanks
I am trying to use ES6's fetch api to post some login data to a java spark server. The GET requests work perfectly, but when I try to POST something, the Promise on the client side stays 'pending'. I checked, and the server receives the request body, and parses it to an object. Using postman, it also returns true or false, so I think something is wrong with the CORS setup. I'm new to that, so i jut let * through, thinking it should work. I am using VueJS, but i don't think that really matters here, thought I'd add this info, maybe it helps. I will post the code below.
JS:
methods: {
login: function () {
data = '"perfectly valid json string"'
this.postData('http://te.st/login', data)
},
postData: function(url, data){
return fetch(url, {
body: data,
method: 'POST',
})
.then(response => response.json())
.then(function (result){
app.response = result
})
}
}
Java:
private static void enableCORS(final String origin, final String methods, final String headers) {
options("/*", (request, response) -> {
String accessControlRequestHeaders = request.headers("Access-Control-Request-Headers");
if (accessControlRequestHeaders != null) {
response.header("Access-Control-Allow-Headers", accessControlRequestHeaders);
}
String accessControlRequestMethod = request.headers("Access-Control-Request-Method");
if (accessControlRequestMethod != null) {
response.header("Access-Control-Allow-Methods", accessControlRequestMethod);
}
return "OK";
});
before((request, response) -> {
response.header("Access-Control-Allow-Origin", origin);
response.header("Access-Control-Request-Method", methods);
response.header("Access-Control-Allow-Headers", headers);
response.type("application/json");
});
}
(called in the code as enableCORS("*","GET,POST","Origin, Content-Type, Access-Control-Allow-Origin"); )
And the endpoint:
post("/login", (req, res) -> {
boolean ret = dao.checkLogin(gson.fromJson(req.body(), User.class));
return gson.toJson(ret);
});
Is there a way to send an object to an API using axios?
This the code I use:
axios.get('/api/phones/create/', {
parameters: {
phone: this.phone
}
})
.then(response => {
console.log(response.data)
})
.catch(function (error) {
console.log(error)
})
on the php side, I have the following:
public function create($phone)
{
return $phone;
}
I get the following error:
GET http://crm2.dev/api/phones/create 500 (Internal Server Error)
dispatchXhrRequest # app.6007af59798a7b58ff81.js:256
xhrAdapter # app.6007af59798a7b58ff81.js:93
dispatchRequest # app.6007af59798a7b58ff81.js:662
app.6007af59798a7b58ff81.js:2266 Error: Request failed with status code 500
at createError (app.6007af59798a7b58ff81.js:600)
at settle (app.6007af59798a7b58ff81.js:742)
at XMLHttpRequest.handleLoad (app.6007af59798a7b58ff81.js:158)
If I try, axios.get('/api/phones/create/hello') I get hello in the console log.
Is there a way to do this?
It depends on what you mean by "send an object".
Since you're using a GET request and passing the object in the parameters, you can serialize it into query params as part of the GET request. This wouldn't really send the object but rather use it to build the query section of the URL for the GET request.
For example, here's how you can make a request to /api/phones/create?phone=123:
axios.get('/api/phones/create/', {
params: {
phone: '123'
}
})
If you want to actually send the object as a serialized JSON to your API, you can use a POST or a PUT request, depending on the semantics of your API.
For example, to send { "phone": "123" } to your api, you could do:
axios.post('/api/phones/create/', {
phone: '123'
});
Note: axios expects the key params for parameters.
First of all try with params instead of parameters.
Axios rely on promises you might need to add promise polyfill to your code if you want to support old browsers.
Here is sample request, Read official docs for more information.
axios.get('/url', {
firstName: 'Fred',
lastName: 'Flintstone'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});