I want to code the multipart-form POST REQUEST below using apollo-datasource-rest
My attempt to code this leads to a BAD REQUEST error
const { RESTDataSource } = require('apollo-datasource-rest');
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
class SalesforceApi extends RESTDataSource {
constructor() {
super();
this.initialize({});
this.getAccessToken()
.then((accessToken) => {
this.headers = {
Authorization: `Bearer ${accessToken}`,
};
});
}
async getAccessToken() {
console.log('Getting Salesforce access token');
try {
const response = await this.post(
'https://test.salesforce.com/services/oauth2/token',
{
username: 'FILTERED#FILTERED',
password: `${'FILTERED'}`,
grant_type: 'password',
client_id: 'FILTERED',
client_secret: 'FILTERED',
},
{
headers: {
'Content-Type': 'multipart/form-data',
},
},
);
const { accessToken } = response;
console.log(`ChangeGear sessionId: ${accessToken}`);
return accessToken;
} catch (error) {
console.log(`${error}`);
}
return 'No access token!!!';
}
module.exports = SalesforceApi;
[server:salesforce:local] POST https://test.salesforce.com/services/oauth2/token (343ms)
[server:salesforce:local] Error: 400: Bad Request
If memory serves correctly, form data is serialized slightly differently hence why the FormData interface exists. And the apollo-datasource-rest's this.post method is just a wrapper around fetch, so something like the below should work.
Instead of passing the body as a JSON object, try something like this
const formData = new FormData();
formData.append('username', 'FILTERED#FILTERED');
// ... more append lines for your data
const response = await this.post(
'https://test.salesforce.com/services/oauth2/token',
formData
{
headers: {
'Content-Type': 'multipart/form-data',
},
},
);
Related
I'm making a request for getting an access_token to an auth0 API.
The request is success, but the data object containing the access token contains weird characters. The thing is that I had that object for 3-4 hours, after that it wasn't retrieved anymore. Any clues on this?
And this is the code:
(async () => {
const client = axios.create({
baseURL: 'https://my_url_to.auth0.com/oauth/token',
headers: {
'Content-Type': 'application/json'
}
});
Log.debug(body);
try {
const resp = await client.post('/', body);
console.log(JSON.stringify(resp.data));
} catch (e) {
Log.error(e);
}
})();
In v1.2.1 fixed this error.
You need to add Accept-Encoding with 'application/json' in axios header.
The default of axios is gzip.
This code will be works
(async () => {
const client = axios.create({
baseURL: 'https://my_url_to.auth0.com/oauth/token',
headers: {
'Content-Type': 'application/json',
'Accept-Encoding': 'application/json'
}
});
Log.debug(body);
try {
const resp = await client.post('/', body);
console.log(JSON.stringify(resp.data));
} catch (e) {
Log.error(e);
}
})();
I would like to generate an ics file then transform it in blob to finally send it through an Zendesk API POST call
The code
const blob = new Blob([icsContent], { type: "application/json" });
const uploadICSFile = await uploadZendeskFile('appointment.ics', blob);
axios POST
export async function uploadZendeskFile(filename: string, fileBlob: Blob): Promise<Upload> {
return await axios.post(
`https://${config.subdomain}.zendesk.com/api/v2/uploads.json?filename=${filename}`,
fileBlob,
{
auth: {
username: '*****',
password: '*****'
},
headers: {
'Content-Type': 'text/calendar',
}
}
);
}
The answer:
Typescript code:
const blob = new Blob([icsContent], { type: "application/octet-stream" });
const uploadICSFile = await uploadZendeskFile('appointment.ics', blob);
I'm trying to upload a file using axios and the request fails. have searched quite a bit seems like everyone is doing the same and works for them. Is there something I'm missing ?
My request in saga looks like this:
function* postUploadUtilityList(list) {
console.log('List', list.data);
const { data } = list;
for (const i in data) {
if (list.data.hasOwnProperty(i)) {
yield call(postUploadUtility, data[i]);
}
}
}
const createFormData = (photo, body) => {
const data = new FormData();
data.append('image', photo);
Object.keys(body).forEach((key) => {
data.append(key, body[key]);
});
return data;
};
function* postUploadUtility(item) {
console.log('item', item);
try {
const body = {
caption: 'utility',
};
const formData = createFormData(item, body);
const apiConfig = {
method: 'post',
baseURL: getBaseUrl(BB),
url: '/client/upload',
data: formData,
headers: {
Accept: 'application/json',
'Content-Type': 'multipart/form-data',
},
};
const res = yield call(http, apiConfig);
if (res.status === 200) {
const { data } = res;
yield put({
type: POST_UTILITY_UPLOAD_SUCCESS,
data,
});
} else {
const { data } = res;
yield put({
type: POST_UTILITY_UPLOAD_FAILURE,
data,
});
}
} catch (e) {
yield put({
type: POST_UTILITY_UPLOAD_FAILURE,
e,
});
}
}
export default function* watchPostUploadUtility() {
yield takeLatest(POST_UTILITY_UPLOAD, postUploadUtilityList);
}
Log looks like as follow:
network call looks like as follow:
Try this solutions, Use image base64 instead of image url
I have the following code which I import and use in a VueJS application.
I want to be able to errors returned by the API centrally and it seems that interceptors would do the job for me but I don't understand where I set them up
import axios from 'axios'
import store from './store/index'
export default () => {
try{
var token = store.state.user.token.token
}catch(err){
var token = ""
}
return axios.create({
baseURL: "http://localhost:3333/api/v1",
headers: {
"Authorization": `Bearer ${token}`
}
})
}
I have tried this, but it does not work.
import axios from 'axios'
import store from './store/index'
axios.interceptors.request.use((config) => {
console.info("debug ", config);
return config;
}, (error) => {
console.error("debug ", error);
return Promise.reject(error);
});
export default () => {
try{
var token = store.state.user.token.token
}catch(err){
var token = ""
}
return axios.create({
baseURL: "http://localhost:3333/api/v1",
headers: {
"Authorization": `Bearer ${token}`
}
})
}
After some fiddling, I have worked it out.
You have to first create an axios object with axios.create(), then assign your intercepters to the object after which you can return the object. Here is the code I used that worked.
var axiosInstance = axios.create({
baseURL: "http://localhost:3333/api/v1",
headers: {
"Authorization": `Bearer ${token}`
},
})
//This allows you to intercept the request before it is sent and alter headers or anyting else that is passed to the axios config.
axiosInstance.interceptors.request.use((config)=>{
return config
}, (error) => {
console.log("Interceptor Request Error" + error)
})
//This allows you to intercept the response and check the status and error messages and if ncessary reject the promise.
axiosInstance.interceptors.response.use((response) => {
console.log(response.data)
return response
}, (error) => {
console.log("Interceptor Response Error" + error)
})
return axiosInstance
Now I know how to do this, I could move my Authorization code out of the create function and put it in the request interceptor axiosInstance.interceptors.request.use
I try to do a simple post request with axios.
My code snippet:
const getOauthToken = async () => {
try {
const headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'X-ProxyPass' : '...',
}
const data = {
...
}
return await axios.post('/oauth2/token', data, {headers: headers});
} catch (error) {
throw new Error(`Unable to get an authentication token. Reason ${error}`);
}
};
This call fails with http 400. When I set the headers as default with
axios.defaults.headers.post['X-ProxyPass'] = '...';
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
then it works.
Found the solution in the documentation of axios.
If I use "application/x-www-form-urlencoded", I have to use querystring to serialize in the needed format.
return await axios.post('/oauth2/token', querystring.stringify(data), {headers: headers});
But why it works, when I set the headers as default headers i still mysterious.