Action:
export const filesDownload = postData => (dispatch) => {
console.log(postData);
fetch(`http://${ip}:8000/api/v1/integrator/email/need_attachment/`, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
body: JSON.stringify(postData),
})
.then(res => console.log(res.json()))
.then(files =>
dispatch({
type: GET_FILES,
payload: files,
}));
};
Reducer:
case GET_FILES :
return{
...state,
file: action.payload
}
Component:
OnEnableDisplay = (event) => {
this.props.filesDownload(attachements_call);
};
Above is my code I want to access the response from the API which I get in the action in the component and set the state again so that I can show the data I get.
I am new to redux, please spare a little time to help guys.
Related
I have managed to make this run: How to modify axios instance after exported it in ReactJS?
And it looks like this:
import axios from 'axios';
import constants from '../constants.js';
import Cookies from 'js-cookie';
const API = axios.create({
baseURL: `${constants.urlBackend}`,
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
});
API.interceptors.request.use(
config => {
var accesstoken = Cookies.get('accesstoken');
if (accesstoken) {
config.headers.Authorization = `Bearer ${accesstoken}`;
} else {
delete API.defaults.headers.common.Authorization;
}
return config;
},
error => Promise.reject(error)
);
export default API;
And this is an example usage
getUserList() {
API.get('/userlist')
.then(response => {
this.setState({
userList: response.data
}, () => {
console.log(this.state.userList)
});
})
}
But now im confused because I dont understand how to use this with a post so I can pass some data to it, similar to this
axios({
method: 'post',
url: constants.urlBackend + "/register",
data: qs.stringify({ email, password }),
headers: {
'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
}
})
But using the above object.
API.post('/user/update/'+this.state.rowId).then(response => {
//some sort of body {email,password}
})
Have you tried
API.post(
'/user/update/' + this.state.rowId, {
email,
password
}).then(response => {})
In my componentDidMount function I call AsyncStorage to get some saved value and then make a GET request and fetch data like below:
componentDidMount() {
AsyncStorage.getItem("token").then(value => {
const url = 'my url';
console.log('token:' + value)
return fetch(url, {
method: 'GET',
headers: new Headers({
'Content-Type': 'application/json',
'token': 'abcd',
'jwt': value
})
})
.then((response) => response.json())
.then((responseJson) => {
this.setState({
dataSource: responseJson,
isLoading: false,
getValue: value
})
})
.catch((Error) => {
console.log(Error)
})
})
}
Now, I need to make another GET request. Suppose if I want to make the same request again in this function , how can I do that?
I solved it very easily from the suggested comments. I did the API call part in two different functions and then called these two functions inside ComponentDidMount like below code-
getFirstApiResposnse() {
AsyncStorage.getItem("token").then(value => {
const url = 'my url';
console.log('token:'+ value)
return fetch(url, {
method: 'GET',
headers: new Headers({
'Content-Type' : 'application/json',
'token': 'abcd',
'jwt': value
})
})
.then((response)=> response.json() )
.then((responseJson) => {
this.setState({
dataSource: responseJson,
isLoading: false,
getValue: value
})
})
.catch((Error) => {
console.log(Error)
});
}
)
};
getSecondApiResponse() {
AsyncStorage.getItem("token").then(value => {
const url = 'my url';
console.log('token:'+ value)
return fetch(url, {
method: 'GET',
headers: new Headers({
'Content-Type' : 'application/json',
'token': 'abcd',
'jwt': value
})
})
.then((response)=> response.json() )
.then((responseJson) => {
console.log('####:'+responseJson.cat_note)
this.setState({
isLoading: false,
getValue: value,
})
})
.catch((Error) => {
console.log(Error)
});
}
)
}
componentDidMount() {
this.getFirstApiResponse();
this.getSecondApiResponse();
}
You can also use Promise.all(). Which comes handy with multiple requests. Also, we can use helper library such as async and use its forEach, waterFall, series, parallel, etc methods depending on project needs. These things make our code more readable and scalable.
This is a simple Post request using Axios inside Vue:
import axios from 'axios'
export default {
name: 'HelloWorld',
props: {
msg: String
},
mounted () {
const code = 'test'
const url = 'http://localhost:3456/'
axios.post(url, code, { headers: {'Content-type': 'application/x-www-form-urlencoded', } }).then(this.successHandler).catch(this.errorHandler)
},
methods: {
successHandler (res) {
console.log(res.data)
},
errorHandler (error) {
console.log(error)
}
}
}
The Get method works fine. But Post stay as "Pending" on Network tab. I can confirm that there is a Post method on my webservice and it return something (tested on Postman).
UPDATE
Sending code as a param:
axios(url, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
params: {
code : 'test'
},
}).then(this.successHandler).catch(this.errorHandler)
WEBSERVICE
server.post('/', (req, res, next) => {
const { code } = req.params
const options = {
validate: 'soft',
cheerio: {},
juice: {},
beautify: {},
elements: []
}
heml(code, options).then(
({ html, metadata, errors }) => {
res.send({metadata, html, errors})
next()
})
})
I think there's issue with your axios request structure.
Try this:
const URL = *YOUR_URL*;
axios(URL, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
data: *YOUR_PAYLOAD*,
})
.then(response => response.data)
.catch(error => {
throw error;
});
If you're sending a query param:
axios(URL, {
method: 'POST',
headers: {
'content-type': 'application/json',
},
params: {
code: 'your_string'
},
})
if it is path variable you can set your url:
const url = `http://localhost:3456/${code}`
Let me know if the issue still persists
I also was facing the same. Network call was pending all the time and Mitigated it by passing the response back from server.js(route file) e.g(res.json(1);) and it resolved the issue
I am pretty new to react native. I am using react navigation in my react-native app. I am passing some props from one screen to another, and I need to use one of the props in a fetch I am trying to execute within the componentDidMount lifecycle method. With everything I have tried, it sends the value for the "type" key, but it sends nothing for the "location" key (see code below). Could someone help me with what am I missing or doing wrong? I have tried several things to pass the prop but nothing has worked yet.
componentDidMount() {
const { params } = this.props.navigation.state;
var data = {
type: 'r',
location: params.location
}
return fetch('http://myapisite', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
}
)
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson,
}, function() {
// do something with new state
});
})
.catch((error) => {
console.error(error);
});
}
I was able to resolve the issue. I am not 100% certain why what I had didn't work, but when I changed it to the following, it worked as expected:
const {state} = this.props.navigation;
var data = {
type: 'restaurant',
location: state.params.location
}
return fetch('http://mylink', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(data)
}
)
.then((response) => response.json())
.then((responseJson) => {
this.setState({
isLoading: false,
dataSource: responseJson,
}, function() {
// do something with new state
});
})
.catch((error) => {
console.error(error);
});
I am developing an application where there are lots of async actions. I wanted to go with redux-saga but most have insisted to continue with redux-thunk. In redux-thunk, inside each action we have to work with async operation using then, dispatch, catch, etc. This makes looks actions so messy and lots of code will be repeated. I wanted to create a generic dataLoader for the use of redux-thunk and axios but could not consider for both post(might be token or not) and get option.
Here is my attempt:
export class Company {
/**
* Generic api data loader
*/
static dataLoader(apiUri, onSuccess, onError, data, ...actionArguments) {
const requestURL = `${API_BASE}${apiuri}`;
try {
let options;
if (data !== undefined) {
// if we have data to post
options = {
method: 'POST',
url: requestURL,
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
},
};
}
}
return function(dispatch) {
axios(options)
.then(response => {
dispatch({
type: onSucess,
payload: response.data
});
})
.catch(error => {
dispatch({ type: onError, payload: err});
});
}
}
static get(apiUri, onSuccess, onError, ...actionArguments) {
return this.dataLoader(apiUri, onSuccess, onError, undefined, ...actionArguments);
}
/*
* Shorthand POST function
*/
static post(apiUri, onSuccess, onError, data, ...actionArguments) {
return this.dataLoader(apiUri, onSuccess, onError, data, ...actionArguments);
}
}
I want to convert the following code to further this one:
export function showResultofApartment() {
return (dispatch) => {
dispatch({ type: 'APARTMENT_FETCH_START' });
const token = localStorage.getItem('token');
return axios.get(`${API_URL}/newoffers/apartment/`)
.then((response) => {
console.log('response apart', response.data);
dispatch({ type: 'APARTMENT_FETCH_SUCCESS', payload: response.data });
})
.catch((err) => {
dispatch({ type: 'APARTMENT_FETCH_FAILURE', payload: err });
});
};
}
to such or more efficient than this:
export function showResultofApartment() {
return(dispatch) => {
dispatch({ type: APARTMENT_FETCH_START });
const token = localStorage.getItem('token');
return Company.get('/apartments', APARTMENT_FETCH_SUCCESS, APARTMENT_FETCH_ERROR);
// if post then Company.post('/apartment', APARTMENT_POST_SUCCESS, APARTMENT_POST_ERROR, data)
}
}
This way it is considering only post request(if data !== undefined). How should i handle for both get and post efficiently?
Okay, why don't you handle it like this:
Company.js
import { merge } from 'lodash';
import axios from 'axios';
function getHeaders() {
return {
'Content-Type': 'application/json'
};
}
export class Company {
static callAPI(endpoint, extendedOptions, onSuccess, onError) {
const initalHttpData = {
method: 'GET', // By default it's GET in case you didnt specify anything
headers: getHeaders(),
url: `${API_BASE}${endpoint}`
};
// merge takes care of replacing or adding the specific key's provided via the extendedOptions
const options = merge(initalHttpData, extendedOptions);
// Fire the request for the prepared options.
let request = axios(options);
// The request once fired, needs it's success handler and error handler.
return function(dispatch) {
request
.then(response => {
dispatch({
type: onSucess,
payload: response.data
});
})
.catch(error => {
dispatch({ type: onError, payload: err});
});
}
};
}
Then we can use actions to specifically pass things to this api util:
GET API call:
// GET Action
export function showResultofApartment() {
return (dispatch) => {
dispatch({ type: APARTMENT_FETCH_START });
const token = localStorage.getItem('token');
// FOR GET API
return Company.callApi('/apartments', {}, APARTMENT_FETCH_SUCCESS, APARTMENT_FETCH_ERROR);
}
}
POST API call:
// POST Action
export function showResultOfAppartmentPost() {
return (dispatch) => {
dispatch({ type: APARTMENT_FETCH_START });
const token = localStorage.getItem('token');
// This will merge, essentially replace the method=GET once it gets called.
const extendedOptions = {
method: 'POST',
body: JSON.stringify(data),
headers: {
'X-Requested-With': 'XMLHttpRequest',
}
}
// FOR GET API
return Company.callApi('/apartments', extendedOptions, APARTMENT_FETCH_SUCCESS, APARTMENT_FETCH_ERROR);
}
Thus, giving the action, to define it's own set of API body or requests.