How to return value from json-server on post request? - json-server

The issue
GET /api/get-request works correctly, and `{ x: 'x' } is returned to the frontend
POST /api/post-request works too but returns empty body
How I run json-server:
json-server src/configs/api/mocks/json-server-generator.js --routes src/configs/api/mocks/json-server-routes.json --watch"
json-server-routes.json
{
"/api/getrequest": "/getrequest",
"/api/postrequest": "/postrequest",
}
json-server-generator.js
module.exports = () => {
return {
getrequest: { x: 'x' },
postrequest: { y: 'y' }
}
}
Requests are made via fetch:
fetch(url, {
method,
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(payload)
})

Related

capacitor community/http handle errors

I often use Axios to perform requests in my applications, however due to incompatibility with iphone, I had to use the capacitor-community/http library, however the try catch blocks are always returning success, even if there was an error in the request. How can I handle errors using this library?
try {
await Requester.auth.public.login(formData);
this.$store.dispatch('login', user);
this.$root.$emit('showToast', {
text: 'Seja bem vindo!',
color: 'success',
});
this.$router.push({ name: 'Cotacao' });
} catch (err) {
this.$root.$emit('showToast', {
text: err.response?.data ?? err.toString(),
color: 'error',
});
} finally {
this.loading.submitForm = false;
}
},
My request
const login = async (formData: AuthLoginFormData): Promise<User> => {
const res: HttpResponse = await Http.post({
url: `${BASE_URL}public/auth/login`,
headers: {
'Content-Type': 'application/json',
},
data: formData,
webFetchExtra: {
credentials: 'include',
},
});
return res.data;
};
Install Latest https://github.com/capacitor-community/http plugin
use function
public async login(formData: AuthLoginFormData){
let options = {
url: `${BASE_URL}public/auth/login`,
headers: {
'Content-Type': 'application/json',
},
data: formData,
webFetchExtra: {
credentials: 'include',
}
};
let response: HttpResponse = await Http.request(options);
if (response.status === 200) {
return Promise.resolve(res);
}
return Promise.reject(response.data);
}

How to format axios GET call with nested params

I want to fetch an API
The call look like this;
const instance = axios.create({
method: 'GET',
uri: 'https://api.compound.finance/api/v2/account',
timeout: timeout,
params: {
block_number:'0',
page_number:'1',
page_size:'250',
max_health: {
value:'1'
},
},
headers: {
"Content-Type": "application/json",
},
});
The API spec https://compound.finance/docs/api
{
"addresses": [] // returns all accounts if empty or not included
"block_number": 0 // returns latest if given 0
"max_health": { "value": "10.0" }
"min_borrow_value_in_eth": { "value": "0.002" }
"page_number": 1
"page_size": 10
}
However the output URI contains some character to replace { } arround max_health value
The uri end up looking like this;
/api/v2/account?block_number=0&page_number=1&page_size=250&max_health=%7B%22value%22:%221%22%7D'
I have tried qs but it's not working as I expect.
I have tryed this to ;
let params = {
block_number:'0',
page_number:'1',
page_size:'250',
max_health: {
value:'1'
}
}
await instance.get('https://api.compound.finance/api/v2/account',JSON.stringify(params)).then( (response) => {...})
It gave me this error ;
TypeError: Cannot use 'in' operator to search for 'validateStatus' in
{"block_number":"0","page_number":"1","page_size":"250","max_health":{"value":"1"}}
Any help would be appreciated.
The fix;
Use paramSerializer
const instance = axios.create({
method: 'GET',
uri: 'https://api.compound.finance/api/v2/account',
timeout: timeout,
params: {
block_number:'0',
page_number:'1',
page_size:'250',
max_health: {
value:'1'
},
},
paramsSerializer: function (params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
},
headers: {
"Content-Type": "application/json",
},
});

Hosting a Forge Autodesk viewer on Github

I've an issue with the Forge viewer I'm developping : Im' trying to host it using Github-page, but it doesn't seem to work correctly.
The issue is on the File tree : when I load the viewer page from the Github pages, the file tree seems stuck on "Loading...". However, it correctly loads when I load the page from localhost.
The code of the File tree :
$(document).ready(function () {
prepareAppBucketTree();
$('#refreshBuckets').click(function () {
$('#appBuckets').jstree(true).refresh();
});
$('#createNewBucket').click(function () {
createNewBucket();
});
$('#createBucketModal').on('shown.bs.modal', function () {
$("#newBucketKey").focus();
})
$('#hiddenUploadField').change(function () {
var node = $('#appBuckets').jstree(true).get_selected(true)[0];
var _this = this;
if (_this.files.length == 0) return;
var file = _this.files[0];
switch (node.type) {
case 'bucket':
var formData = new FormData();
formData.append('fileToUpload', file);
formData.append('bucketKey', node.id);
$.ajax({
url: '/api/forge/oss/objects',
data: formData,
processData: false,
contentType: false,
type: 'POST',
success: function (data) {
$('#appBuckets').jstree(true).refresh_node(node);
_this.value = '';
}
});
break;
}
});
});
function createNewBucket() {
var bucketKey = $('#newBucketKey').val();
var policyKey = $('#newBucketPolicyKey').val();
console.log(bucketKey)
jQuery.post({
url: '/api/forge/oss/buckets',
contentType: 'application/json',
data: JSON.stringify({ 'bucketKey': bucketKey, 'policyKey': policyKey }),
success: function (res) {
$('#appBuckets').jstree(true).refresh();
$('#createBucketModal').modal('toggle');
},
error: function (err) {
if (err.status == 409)
alert('Bucket already exists - 409: Duplicated')
console.log(err);
}
});
}
function prepareAppBucketTree() {
$('#appBuckets').jstree({
'core': {
'themes': { "icons": true },
'data': {
"url": '/api/forge/oss/buckets',
"dataType": "json",
'multiple': false,
"data": function (node) {
return { "id": node.id };
}
}
},
'types': {
'default': {
'icon': 'glyphicon glyphicon-question-sign'
},
'#': {
'icon': 'glyphicon glyphicon-cloud'
},
'bucket': {
'icon': 'glyphicon glyphicon-folder-open'
},
'object': {
'icon': 'glyphicon glyphicon-file'
}
},
"plugins": ["types", "state", "sort", "contextmenu"],
contextmenu: { items: autodeskCustomMenu }
}).on('loaded.jstree', function () {
$('#appBuckets').jstree('open_all');
}).bind("activate_node.jstree", function (evt, data) {
if (data != null && data.node != null && data.node.type == 'object') {
// $("#MyViewerDiv").empty();
var urn = data.node.id;
getForgeToken(function (access_token) {
jQuery.ajax({
url: 'https://developer.api.autodesk.com/modelderivative/v2/designdata/' + urn + '/manifest',
headers: { 'Authorization': 'Bearer ' + access_token },
success: function (res) {
if (res.status === 'success') callByUrn('urn:'+urn);
else $("#MyViewerDiv").html('The translation job still running: ' + res.progress + '. Please try again in a moment.');
},
error: function (err) {
var msgButton = 'This file is not translated yet! ' +
'<button class="btn btn-xs btn-info" onclick="translateObject()"><span class="glyphicon glyphicon-eye-open"></span> ' +
'Start translation</button>'
$("#MyViewerDiv").html(msgButton);
}
});
})
}
});
}
function autodeskCustomMenu(autodeskNode) {
var items;
switch (autodeskNode.type) {
case "bucket":
items = {
uploadFile: {
label: "Upload file",
action: function () {
uploadFile();
},
icon: 'glyphicon glyphicon-cloud-upload'
}
};
break;
case "object":
items = {
translateFile: {
label: "Translate",
action: function () {
var treeNode = $('#appBuckets').jstree(true).get_selected(true)[0];
translateObject(treeNode);
},
icon: 'glyphicon glyphicon-eye-open'
}
};
break;
}
return items;
}
function uploadFile() {
$('#hiddenUploadField').click();
}
function translateObject(node) {
$("#MyViewerDiv").empty();
if (node == null) node = $('#appBuckets').jstree(true).get_selected(true)[0];
var bucketKey = node.parents[0];
var objectKey = node.id;
jQuery.post({
url: '/api/forge/modelderivative/jobs',
contentType: 'application/json',
data: JSON.stringify({ 'bucketKey': bucketKey, 'objectName': objectKey }),
success: function (res) {
$("#MyViewerDiv").html('Translation started! Please try again in a moment.');
},
});
}
Please note that Github Pages are used for serving static pages without any special server-side logic. Your Forge application requires a server to talk to as well, for example, to obtain a list of buckets for the tree view (by making a request to /api/forge/oss/buckets).
You could potentially host your application's server-side logic on something like Heroku, and then have your static HTML/CSS/JavaScript page on Github talk to that server (for example, https://my-forge-app.herokuapp.com/api/forge/oss/buckets). Just be careful about CORS.

Passing headers with axios POST request

I have written an Axios POST request as recommended from the npm package documentation like:
var data = {
'key1': 'val1',
'key2': 'val2'
}
axios.post(Helper.getUserAPI(), data)
.then((response) => {
dispatch({type: FOUND_USER, data: response.data[0]})
})
.catch((error) => {
dispatch({type: ERROR_FINDING_USER})
})
And it works, but now I have modified my backend API to accept headers.
Content-Type: 'application/json'
Authorization: 'JWT fefege...'
Now, this request works fine on Postman, but when writing an axios call, I follow this link and can't quite get it to work.
I am constantly getting 400 BAD Request error.
Here is my modified request:
axios.post(Helper.getUserAPI(), {
headers: {
'Content-Type': 'application/json',
'Authorization': 'JWT fefege...'
},
data
})
.then((response) => {
dispatch({type: FOUND_USER, data: response.data[0]})
})
.catch((error) => {
dispatch({type: ERROR_FINDING_USER})
})
When using Axios, in order to pass custom headers, supply an object containing the headers as the last argument
Modify your Axios request like:
const headers = {
'Content-Type': 'application/json',
'Authorization': 'JWT fefege...'
}
axios.post(Helper.getUserAPI(), data, {
headers: headers
})
.then((response) => {
dispatch({
type: FOUND_USER,
data: response.data[0]
})
})
.catch((error) => {
dispatch({
type: ERROR_FINDING_USER
})
})
Here is a full example of an axios.post request with custom headers
var postData = {
email: "test#test.com",
password: "password"
};
let axiosConfig = {
headers: {
'Content-Type': 'application/json;charset=UTF-8',
"Access-Control-Allow-Origin": "*",
}
};
axios.post('http://<host>:<port>/<path>', postData, axiosConfig)
.then((res) => {
console.log("RESPONSE RECEIVED: ", res);
})
.catch((err) => {
console.log("AXIOS ERROR: ", err);
})
To set headers in an Axios POST request, pass the third object to the axios.post() call.
const token = '..your token..'
axios.post(url, {
//...data
}, {
headers: {
'Authorization': `Basic ${token}`
}
})
To set headers in an Axios GET request, pass a second object to the axios.get() call.
const token = '..your token..'
axios.get(url, {
headers: {
'Authorization': `Basic ${token}`
}
})
const data = {
email: "me#me.com",
username: "me"
};
const options = {
headers: {
'Content-Type': 'application/json',
}
};
axios.post('http://path', data, options)
.then((res) => {
console.log("RESPONSE ==== : ", res);
})
.catch((err) => {
console.log("ERROR: ====", err);
})
All status codes above 400 will be caught in the Axios catch block.
Also, headers are optional for the post method in Axios
You can also use interceptors to pass the headers
It can save you a lot of code
axios.interceptors.request.use(config => {
if (config.method === 'POST' || config.method === 'PATCH' || config.method === 'PUT')
config.headers['Content-Type'] = 'application/json;charset=utf-8';
const accessToken = AuthService.getAccessToken();
if (accessToken) config.headers.Authorization = 'Bearer ' + accessToken;
return config;
});
Shubham's answer didn't work for me.
When you are using the Axios library and to pass custom headers, you need to construct headers as an object with the key name 'headers'. The 'headers' key should contain an object, here it is Content-Type and Authorization.
The below example is working fine.
var headers = {
'Content-Type': 'application/json',
'Authorization': 'JWT fefege...'
}
axios.post(Helper.getUserAPI(), data, {"headers" : headers})
.then((response) => {
dispatch({type: FOUND_USER, data: response.data[0]})
})
.catch((error) => {
dispatch({type: ERROR_FINDING_USER})
})
We can pass headers as arguments,
onClickHandler = () => {
const data = new FormData();
for (var x = 0; x < this.state.selectedFile.length; x++) {
data.append("file", this.state.selectedFile[x]);
}
const options = {
headers: {
"Content-Type": "application/json",
},
};
axios
.post("http://localhost:8000/upload", data, options, {
onUploadProgress: (ProgressEvent) => {
this.setState({
loaded: (ProgressEvent.loaded / ProgressEvent.total) * 100,
});
},
})
.then((res) => {
// then print response status
console.log("upload success");
})
.catch((err) => {
// then print response status
console.log("upload fail with error: ", err);
});
};
axios.post can accept 3 arguments that the last argument can accept a config object that you can set header.
Sample code with your question:
var data = {
'key1': 'val1',
'key2': 'val2'
}
axios.post(Helper.getUserAPI(), data, {
headers: {Authorization: token && `Bearer ${ token }`}
})
.then((response) => {
dispatch({type: FOUND_USER, data: response.data[0]})
})
.catch((error) => {
dispatch({type: ERROR_FINDING_USER})
})
If you are using some property from vuejs prototype that can't be read on creation you can also define headers and write i.e.
storePropertyMaxSpeed(){
axios
.post(
"api/property",
{
property_name: "max_speed",
property_amount: this.newPropertyMaxSpeed,
},
{
headers: {
"Content-Type": "application/json",
Authorization: "Bearer " + this.$gate.token(),
},
}
)
.then(() => {
//this below peace of code isn't important
Event.$emit("dbPropertyChanged");
$("#addPropertyMaxSpeedModal").modal("hide");
Swal.fire({
position: "center",
type: "success",
title: "Nova brzina unešena u bazu",
showConfirmButton: false,
timer: 1500,
});
})
.catch(() => {
Swal.fire("Neuspješno!", "Nešto je pošlo do đavola", "warning");
});
};
Interceptors
I had the same issue and the reason was that I hadn't returned the response in the interceptor. Javascript thought, rightfully so, that I wanted to return undefined for the promise:
// Add a request interceptor
axios.interceptors.request.use(function (config) {
// Do something before request is sent
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});

Is it possible to change the header config of an AngularJS $resource object?

Here's my code:
var userAuth;
var user = $resource('https://myservice.com/user/:id/', {id: '#_id'} ,{
login: {
method: 'POST',
params: {
id: 'login'
},
transformResponse: function(data) {
data = angular.fromJson(data);
userAuth = 'Kinvey '+data._kmd.authtoken;
return data;
}
},
current: {
method: 'GET',
params: {
id: '_me'
},
headers: {
'Authorization': userAuth
}
}
});
I want to be able to use the updated contents of the userAuth variable in the headers of the current endpoint of the resource, after it has been modified in the transformResponse of the login call. Is this even possible? If so, how?
EDIT: I am using Angular version 1.1.3 - this question is about changing the headers in the resource once they have been set, not settings them initially. Thanks
Assuming you are using the current stable release (1.0.8), although this feature is documented in the $resource page it has not been released.
AngularJS resource not setting Content-Type
EDIT:
See my comment below for the explaination of this code.
var customerHeaders = {
'Authorization' : ''
};
var user = $resource('https://myservice.com/user/:id/', {id: '#_id'} ,{
login: {
method: 'POST',
params: {
id: 'login'
},
transformResponse: function(data) {
data = angular.fromJson(data);
customHeaders.Authorization = 'Kinvey '+data._kmd.authtoken;
return data;
}
},
current: {
method: 'GET',
params: {
id: '_me'
},
headers: customHeaders
}
});