How to upload FormData using Axios? - javascript

I am trying to upload 3 photos from frontend using formData. It will call an external API to make the upload. But encountered some errors as below.
Frontend upload
const formData = new FormData()
formData.append('photoA', this.photoA)
formData.append('photoB', this.photoB)
formData.append('photoC', this.photoC)
axios.post(`http://localhost:4172/uploadDocs`,
{
data: formData,
accessToken: store.state.token
},
{ headers: {
// 'Content-Type': 'Application/json',
// 'x-access-token': localStorage.getItem('token')
}
}
).then (function (response) {
return response.data
})
Nodejs upload API
async uploadDocs (req, res) {
const options = {
method: "POST",
url: "https://example.com/api/v1/users/uploadDocuments?access_token=" + req.body.accessToken,
headers: {
//"Authorization": "Basic " + auth,
//"Content-Type": "multipart/form-data"
},
data: req.body.data
};
try {
request(options, function (err,response,body){
if (err) {
res.send(err)
} else {
res.send(response.body)
}
})
} catch (error) {
res.status(400).send({
error: "Server error."
})
}
}
So there are 2 errors here:
a) Frontend error: It keeps giving Cannot POST / error in html
b) Backend error:
<h1>Cannot read property 'photoA' of undefined</h1>
<h2></h2>
<pre></pre>
Been struggling with this for days. Any help will be very much appreciated.

Related

Trying to send a String (username) from the client to the server in React and Typescript

I am trying to send the username of a logged-in person from the Client to the Server as a string. I am already sending a file (image) but I also want to send a string as well.
Essentially what I wanna do is in the Server Side File to replace the 'public_id' with username from Client-side.
As you can see below I am already sending the image (file) that I want to the server. I have used console.log(loggedInUser?.username); to show the string that I want to be sent.
Hope this was enough to explain what I am trying to do. Thanks in advance.
Client Side file
console.log(loggedInUser?.username);
const uploadImage = async (base64EncodedImage: string) => {
try {
await fetch('/api/upload', {
method: 'POST',
body: JSON.stringify({ data: base64EncodedImage }),
headers: { 'Content-type': 'application/json' },
});
} catch (error) {
console.error(error);
}
};
Server side file
app.post("/api/upload", async (req, res) => {
try {
const fileStr = req.body.data;
const uploadedResponse = await cloudinary.uploader.upload(fileStr, {
upload_preset: "geekyimages",
public_id: "public_id",
invalidate: true,
});
console.log(uploadedResponse);
res.json({ msg: "Uploaded" });
} catch (error) {
res.status(500).json({ err: "Something went wrong" });
}
});
Just send both inside a single JSON-Object:
// client side
await fetch('/api/upload', {
method: 'POST',
body: JSON.stringify({
data: base64EncodedImage,
username: loggedInUser?.username
}),
headers: { 'Content-type': 'application/json' },
});
// server side
const username = req.body.username;
From here
await fetch('/api/upload', {
method: 'POST',
body: JSON.stringify({ data: base64EncodedImage }),
headers: { 'Content-type': 'application/json' },
});
Just add a username in the body like
await fetch('/api/upload', {
method: 'POST',
body: JSON.stringify({ data: base64EncodedImage, username: username: loggedInUser?.username || "SOME_DEFAULT_VALUE" }), // The default value is in case you an have a null or undefined username
headers: { 'Content-type': 'application/json' },
You can also prevent this behavior adding this check
if (loggedInUser?.username) ... // The code without default value
else { // A message }

How to resolve Empty error with status code 500 axios?

this is my code :
Express Routes:
router.route('/block')
.post(controller.ticketBlocking);
Express Controller:
const axios = require('axios');
const OAuth = require('oauth-1.0a');
const crypto = require('crypto');
const ticketBlocking = (req, res) => {
const data = JSON.stringify({
source = req.body.source
});
const oauth = OAuth({
consumer: {
key: '....', //Hided the key
secret: '....', //Hided the secret
},
signature_method: 'HMAC-SHA1',
hash_function(base_string, key) {
return crypto.createHmac('sha1', key).update(base_string).digest('base64');
}
});
const request_data = {
url: 'http://link.vvv/blockTicket',
method: 'post',
};
axios({
method: request_data.method,
url: request_data.url,
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
...oauth.oauth.toHeader(oauth.oauth.authorize(request_data)),
},
data : data
})
.then((response) => {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
if (error.response) {
console.log(error.response.data);
console.log(error.response.status);
} else if (error.request) {
console.log(error.request);
} else {
console.log('Error', error.message);
}
console.log(error.config);
});
};
the npm package which am using is - "oauth-1.0a"
The problem am facing is, when i use GET method with different end point, i get an output but when ever i use POST method am getting an empty error with status code 500
I dont know where is the mistake, am using oauth1.0a for authorization, please help !

Linkedin api V2 upload a video in node JS

I'm looking for uploading in node JS a video throught the linkedin API V2 , butI'm still receiving a status code 403. I correctly followed the steps in the documentation. (https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/vector-asset-api#register-an-upload-for-video)
let req = request(`https://assets.mixkit.co/videos/2125/2125-720.mp4`)
.pipe(fs.createWriteStream('video.mp4'));
req.on('close', ()=>{
request({
url: uploadUrl,
method: 'POST',
headers: {
"x-amz-server-side-encryption-aws-kms-key-id": "MY_ID",
"x-amz-server-side-encryption": "aws:kms",
"Content-Type": "application/octet-stream"
},
encoding: null,
body: fs.createReadStream('video.mp4')
}, (error, response, body) => {
if (error) {
cb(error)
} else {
cb({response: response, body: body, url: uploadUrl,})
}
});
});
It's working when using the CURL command https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/vector-asset-api#upload-the-video . , but I need to do it in node js.
Any help is greatly appreciated :)
finally I found the solution :)
Working code
let req = request(`https://assets.mixkit.co/videos/2125/2125-720.mp4`)
.pipe(fs.createWriteStream('video.mp4'));
req.on('close', ()=>{
fs.readFile('video.mp4', function(err, data) {
if (err) throw err;
var encodedImage = new Buffer(data)
request({
url: url,
method: 'PUT',
headers: {
"x-amz-server-side-encryption-aws-kms-key-id": "MY_ID",
"x-amz-server-side-encryption": "aws:kms",
"Content-Type": "application/octet-stream"
},
encoding: null,
body: encodedImage
}, (error, response, body) => {
if (error) {
cb(error)
} else {
cb({response: response, body: body, url: url, access_token: access_token, data: ''})
}
});
});
});

HTTP Client Request for an AWS API Gateway

I have an angular frontend using typescript and I am trying to make a http request to a AWS API-Gateway. Now the problem is, I need to write the following javascript code as typescript code and send a http request but I do not know how.
The Request to the AWS API gateway needs an AWS Cognito jwtToken (in this case its "accessToken"). I also need to pass the "type", which is the name of the function to be executed on the API (in this case 'POST'). I also need to pass a string which chooses what data I receive.
Auth.currentSession().then(tok => {
const accessToken = tok.getIdToken().getJwtToken();
console.log('from floorview: ' + accessToken);
function requestItem(source) {
$.ajax({
type: 'POST',
url: 'https://XXXXXXXXXX.execute-api.eu-central-1.amazonaws.com/prop/dashboard',
headers: {
Authorization: accessToken
},
data: JSON.stringify({
Source: source.toString(),
tableName: 'h16b-testset',
operation: 'read'
}),
dataType: 'json',
contentType: 'application/json',
success: completeRequest,
error: function ajaxError(jqXHR, textStatus, errorThrown) {
console.error('Error requesting ride: ', textStatus, ', Details: ', errorThrown);
console.error('Response: ', jqXHR.responseText);
alert('An error occured when requesting your unicorn:\n' + jqXHR.responseText);
}
}).then(r => console.log(r));
}
requestItem(996);
function completeRequest(result) {
console.log('Response received from API: ', result);
}
});
}
Now my problem is, how do I write this javascript code as typescript code while using angulars HTTPClient. If there is another method then please tell me. I always get 401s or 403s when I try to run this code using an HTTPClient.
Auth.currentSession().then(tok => {
const accessToken = tok.getAccessToken();
const jwt = accessToken.getJwtToken();
this.authKey = jwt;
const params = new HttpParams().set('Source', '996');
params.append('tableName', 'h16b-testset');
params.append('operation', 'read');
const headers = new HttpHeaders().set('Authorization', this.authKey);
headers.append('content-type', 'application/json');
this.http.request(
'POST',
'https://XXXXXXXX.execute-api.eu-central-1.amazonaws.com/prop/dashboard',
{
headers,
responseType: 'json'
}
).subscribe(
res => {
console.log('hallo' + res);
},
err => {
console.log('error occured with httpclient: ' + err.message);
}
);
});
You can write something like the following (using concatMap operator):
import { from } from 'rxjs';
import { concatMap } from 'rxjs/operators';
export class AuthService {
constructor(private http: HttpClient) {
from(Auth.currentSession())
.pipe(concatMap(tok => this.requestItem(tok, 996)))
.subscribe(
result => console.log('Response received from API: ', result),
err => {
console.log('error occured with httpclient: ' + err.message);
}
);
}
requestItem(token, source) : Observable<any> {
this.http.post(url, {
Source: source.toString(),
tableName: 'h16b-testset',
operation: 'read'
},
headers,
params
);
}
}
Rewrite your http client as:
this.http.post(
'https://XXXXXXXX.execute-api.eu-central-1.amazonaws.com/prop/dashboard',
{
Source: '<id>',
tableName: 'h16b-testset',
operation: 'read'
},
{
headers: new HttpHeaders({'Content-type': 'application/json', 'Authorization': '<token>'})
}
).subscribe(res=> console.log(res), failure => console.error(failure))
This way you will send source in body of request and with authorization token in header.
For more info about HttpClient please see https://angular.io/guide/http.

React and NodeJS: How can i use received data from Server on Client?

I want to use received data from server on client . I use a NodeJS Server with NextJS and React.
I use this function on the server:
function addEmailToMailChimp(email, callback) {
var options = {
method: 'POST',
url: 'https://XXX.api.mailchimp.com/3.0/lists/XXX/members',
headers:
{
'Postman-Token': 'XXX',
'Cache-Control': 'no-cache',
Authorization: 'Basic XXX',
'Content-Type': 'application/json'
},
body: { email_address: email, status: 'subscribed' },
json: true
};
request(options, callback);
}
The function will be run from this point:
server.post('/', (req, res) => {
addEmailToMailChimp(req.body.email, (error, response, body) => {
// This is the callback function which is passed to `addEmailToMailChimp`
try {
var respObj = {}; //Initial response object
if (response.statusCode === 200) {
respObj = { success: `Subscribed using ${req.body.email}!`, message: JSON.parse(response.body) };
} else {
respObj = { error: `Error trying to subscribe ${req.body.email}. Please try again.`, message: JSON.parse(response.body) };
}
res.send(respObj);
} catch (err) {
var respErrorObj = { error: 'There was an error with your request', message: err.message };
res.send(respErrorObj);
}
});
})
The try method is used to verify that an email address could be successfully saved to MailChimp. An appropriate message is sent to the client.
On the Client-Side, i use this function to receive and display the data from the server:
handleSubmit() {
const email = this.state.email;
this.setState({email: ""});
fetch('/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({email:email}),
}).then(res => {
if(res.data.success) {
//If the response from MailChimp is good...
toaster.success('Subscribed!', res.data.success);
this.setState({ email: '' });
} else {
//Handle the bad MailChimp response...
toaster.warning('Unable to subscribe!', res.data.error);
}
}).catch(error => {
//This catch block returns an error if Node API returns an error
toaster.danger('Error. Please try again later.', error.message);
});
}
The problem: The email address is saved successfully at MailChimp, but the message is always displayed: 'Error. Please try again later.'from the .catch area. When i log the error from the catch area i get this:
TypeError: Cannot read property 'success' of undefined
Where is my mistake? I have little experience in Node.js environments. I would be very grateful if you could show me concrete solutions. Thank you for your replies.
With fetch theres no data property on the response. You have to call res.json() and return that promise. From there the response body will be read and deserialized.
handleSubmit() {
const email = this.state.email;
this.setState({email: ""});
fetch('/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({email:email}),
})
.then(res => {
console.log(res); //to make sure the expected object is returned
if(res.data.success) {
//If the response from MailChimp is good...
toaster.success('Subscribed!', res.data.success);
this.setState({ email: '' });
} else {
//Handle the bad MailChimp response...
toaster.warning('Unable to subscribe!', res.data.error);
}
}).catch(error => {
//This catch block returns an error if Node API returns an error
toaster.danger('Error. Please try again later.', error.message);
});
}
Two things you need to change:
Call and wait for res.json() to get the response body as json object.
The result of 1. is your 'data' object that you can use directly
handleSubmit() {
//...
fetch('/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({email:email}),
})
.then(res => res.json())
.then(data => {
if(data.success) {
//...
toaster.success('Subscribed!', data.success);
} else {
toaster.warning('Unable to subscribe!', data.error);
}
}).catch(error => {
//...
});
}

Categories