How can I send an object using axios? - javascript

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);
});

Related

Twilio in nodejs is giving "To: undefined error" and is not able to understand data from front end

I just started using Twilio services and there have been a few challenges. The phone number I send from the front end, I'm not able to make out if its actually being sent to the backend route. Whenever the GET request is done, it throws an error
": Required parameter "opts['to']" missing. twilio".
The first error is what I am getting now.
My form sends this to the backend:
case 2:
const Phoneno = {
phone:countryCode+PhoneNumber
};
axios.post('http://localhost:4000/app/otp', { data :Phoneno });
console.log(Phoneno)
my route for sending otp:
router.post('/otp', async(req, res)=>{
client.verify.v2.services("VERIFY_SERVICE_SID")
.verifications
.create({to:req.body.phone, channel: 'sms'})
.then((verification) => {
console.log(verification.status);
return callback(null);
}).catch((e) => {
console.log(e);
return callback(e);
});
});
In that console.log, I get this,
"{phone: '+91**********'}
phone: "+91**********"(my actual number)
[[Prototype]]: Object"
Also, when I hardcode the phone number, the route works perfectly fine. And when i send an HTTP request to the route, then also it sends an otp to my phone number. But is not able to recognize the data sent from the frontend.
My http request:
POST http://localhost:4000/app/otp
Content-Type: application/json
{
"Phoneno":"+9199********"
}
Please help me out. Thanks a lot for looking into it.
You are making a GET request to your back-end, but you are trying to get the data from the request body. GET requests do not have a body.
You're also trying to send the data by passing it in an object as the second argument to axios.get, but that argument should be a config object. To send the data in the query for the GET request it should be under the params key for that object:
const Phoneno = {
phone:countryCode+PhoneNumber
};
axios.get('http://localhost:4000/app/otp', { params: Phoneno });
Then on the back-end, read the data from the query, using req.query.phone:
router.get('/otp', async(req, res)=>{
client.verify.v2.services(VERIFY_SERVICE_SID)
.verifications
.create({to:req.query.phone, channel: 'sms'})
.then((verification) => {
console.log(verification.status);
return callback(null);
}).catch((e) => {
console.log(e);
return callback(e);
});
However, this might not be a good idea because an attacker can easily create a URL to your site and add the phone number in the query parameters and use it to perform SMS pumping.
I'd actually recommend you change your back-end to a POST request and send the data from the front end in a POST request with the data in the body of the request:
const Phoneno = {
phone:countryCode+PhoneNumber
};
axios.post('http://localhost:4000/app/otp', { data: Phoneno });
router.post('/otp', async(req, res)=>{
client.verify.v2.services(VERIFY_SERVICE_SID)
.verifications
.create({to:req.body.data.phone, channel: 'sms'})
.then((verification) => {
console.log(verification.status);
return callback(null);
}).catch((e) => {
console.log(e);
return callback(e);
});

Error: Can't set headers after they are sent node.js

hi guys im fairly new to node.js and I was wonder if I am making a call twice that I am unaware of. I am getting a Error: Can't set headers after they are sent.
export const hearingReminder = functions.https.onRequest((request, response) => {
console.log(request.body)
const payload = {
notification: {
title: 'Upcoming Hearing',
body: 'You have a hearing in one hour.',
}
};
const fcm = request.body.fcm
console.log(request.body.fcm)
try {
response.status(200).send('Task Completed');
return admin.messaging().sendToDevice(fcm, payload);
} catch (error) {
return response.status(error.code).send(error.message);
}
Your code is attempting to send a response twice, under the condition that admin.messaging().sendToDevice generates an error. Instead of sending the 200 response before the call, only send it after the call. Sending the response should always be the very last thing performed in your function.
Your code should be more like this:
admin.messaging().sendToDevice(fcm, payload)
.then(() => {
response.status(200).send('Task Completed');
})
.catch(error => {
response.status(error.code).send(error.message);
})
Note that you don't need to return anything for HTTP type functions. You just need to make sure to handle all the promises, and only send the response after all the promises are resolved.

Getting 401 error when using redmine API for a POST request even though I have included the api key

I am trying to make a post request to create a new wiki page using the redmine-api. I am using JavaScript and Axios. However I a getting a 401 error(UnAuthorize).
My goal is to be able to send a word document to my redmine and create a wiki page.
I am using the Api key provided and I did enable the rest api feature in my redmine setting
I have included the api key in the header however it is not working.
var wordDocument = "./Redmine.docx"
axios.post('<website url>/uploads.json', {
headers: {
'Content-Type': 'application/octet-stream',
'Cache-Control': 'no-store',
'key': '<api-key>'
},
data:wordDocument
})
.then(function (response) {
console.log("succeeed---> ");
console.log (response)
})
.catch(function (error) {
console.log("failed-----> ");
console.log(error.response.headers)
console.log(error.message)
console.log("failed-----> ");
})
I am getting a status: '401 Unauthorized',
Try using the other authentication methods mentioned in the docs:
x passed in as a "key" parameter
- passed in as a username with a random password via HTTP Basic authentication
- passed in as a "X-Redmine-API-Key" HTTP header (added in Redmine 1.1.0)
https://www.redmine.org/projects/redmine/wiki/Rest_api#Authentication
Also ensure that you're using the correct API key.
You can find your API key on your account page ( /my/account ) when logged in, on the right-hand pane of the default layout.
Alright I got it working.
I did "axios({})" instead of "axios.post". I do not know what the different is? I thought it was the same.
Here is my code for anyone who run into this.\
var wordDocument = "./Redmine.docx"
axios({
method: 'post',
url: '<redmind_url>/uploads.json',
headers: { 'Content-Type': 'application/octet-stream'},
params: { 'key': '<api key>'},
data: wordDocument
})
.then(function (response) {
console.log("succeeed---> ");
console.log(response.data)
})
.catch(function (error) {
console.log("failed-----> ");
console.log(error.response.statusText, "-->", error.response.status);
console.log(error.response.headers)
console.log(error.message)
console.log("failed-----> ");
})

React button connection with database through axios.post()

I have 4 inputs and button which takes all data from them and sends to my PostreSQL database through axios.post() request. Not clearly understand how .then() is working. So, here is my button code which just calls this.addNewPainting function:
<button onClick={ this.addNewPainting }>Submit</button>
Here is my addNewPainting function:
addNewPainting() {
axios.post(`http://localhost:333/api/add`, {
title: this.state.titleInput,
year: this.state.yearInput,
size: this.state.yearInput,
location: this.state.locationInput
})
.then(function(response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
Before this project, I used to put response.data to the array with this.setState, but now I have the database and I'm just stuck.
Here is my controller function:
add_painting: (req, res, next) => {
const db = req.app.get('db');
const { title, year, size, location } = req.body;
console.log(title, year, size, location);
db.add_painting([ title, year, size, location ])
.then( () => res.status(200).send() )
.then( () => res.status(500).send() );
}
And the endpoint:
app.post('/api/add', paintings_controller.add_painting);
For future reading (becase you requested it): I'm not an expert using promises, but it works similarly like the AJAX requests.
When you make a request to the server (GET, POST, PUT, etcetera), you're waiting for a response from this (a collection of data, a message, a succesful/unsuccesful POST/PUT/DELETE, etcetera). Depending of the response, you'll code the expected events (error, success, complete, etcetera).
In this case you're using axios, a new way to do AJAX requests. The equivalent way of the error/success/complete/... events is the then() function. Using this approach you can perform operations that makes new tasks or simply print a response message (in your case) of the server.
From MDN:
The then() method returns a Promise. It takes up to two arguments:
callback functions for the success and failure cases of the Promise.
Let's suppose that we have this snippet of code in AJAX:
$.ajax(
{
url : yourURL,
type : 'POST',
data : yourData,
datatype : 'json',
success : function(data) {
yourSuccessFunction(data);
},
error : function(jqXHR, textStatus, errorThrown) {
yourErrorFunction();
}
});
Using axios, you'll code something like this:
axios.post('/user', {
YourData: yourData
}).then(() => { this.yourSuccessFunction() })
}).catch(() => { this.yourErrorFunction() });
I just found the error. I was making a request to PORT 333 in my axios.post(), but the server was working on port 3333.

Accessing actual server response from Angular $resource

I have an API built in Laravel which returns JSON in a format such as this:
{
"data":{
"errors":{
"username":"The username has already been taken.",
"email":"The email has already been taken."
}
},
"success":true,
"status":400
}
In this case, I'm trying to create a user with a username and email address which already exists. This is the Angular $resource code I'm using inside my controller for that:
var user = new User({
username: $scope.user.username,
email: $scope.user.email,
password: $scope.user.password
});
var response = user.$save(function(data) {
console.log(data);
}, function(data) {
if (data.status === 400) {
angular.forEach(data.data.data.errors, function(error) {
console.log(error);
});
}
});
So what this is doing is sending a POST request to /users on the API and if it comes back with a non-200 status code, it's checking if it's a 400 code which means a validation error and console.log'ing those error messages. Sure enough, I get the error messages output to the console.
What I'm wondering is, if there's a better way to access the error messages than data.data.data.errors. Seen as the API wraps the response data in a data field, and Angular returns the $resource of the request rather than the actual server response, it leads to a rather unsightly amount of properties being used to get the error messages.
Is there a better way to do this?
I think the short answer is 'no'. However, if it were me I would probably shuffle some of the variables to make things a bit nicer.
user.$save(function(data) {
console.log(data);
}, function(response) {
if (response.status === 400) {
var data = response.data.data
angular.forEach(data.errors, function(error) {
console.log(error);
});
}
});
If I had control over the api i would not be wrapping the errors in the redundant tertiary data object. This gives an entirely acceptable bit of code imo.
{
"errors":{
"username":"The username has already been taken.",
"email":"The email has already been taken."
},
"success":true,
"status":400
}
user.$save(function(data) {
console.log(data);
}, function(response) {
var data = response.data
if (data.status === 400) {
angular.forEach(data.errors, function(error) {
console.log(error);
});
}
});

Categories

Resources