I have the following code:
//agent.js
import axios from 'axios';
axios.defaults.baseURL = 'https://localhost:5001/api';
const requests = {
createUser: (payload) => {
axios.post('/users/create', payload);
},
getUsers: () => {
axios.get('/users').then((r) => {
console.log(r.data); //outputs the json response
return r.data;
});
}
};
const agent = {
requests
};
export default agent;
//reactComponent.js
import agent from './agent';
function Userlist() {
const users = agent.requests.getUsers();
console.log(users); //outputs undefined
}
What am I doing wrong as I get an undefined when making the request from my reactComponent.js.
Because you are not returning anything in your getUsers function.
getUsers: () => {
axios.get('/users').then((r) => {
console.log(r.data); //outputs the json response
return r.data;
});
}
Remove the function bracket and it should work,
getUsers: () =>
axios.get('/users').then((r) => {
console.log(r.data); //outputs the json response
return r.data;
});
Related
Hi I'm using axios to call API, Now the problem is Whenever I call API it's returning promise with Array as a result instead of actual value.
Here is the code:
export const GetResults=async(arrays)=>{debugger
let res=await arrays?.map(async (i) => {
const response= await callAPI(i);
return response
})
return res
}
import {GetResults} from'../../someFun'
const callMe=async()=>{debugger
const res= await GetResults(["1","2","3")
console.log( res)========/Promise
}
const callAPI = (
id?: string,
): Promise<void> => {
const params = {
id: id,
};
return api
.get<>('api end point', { params })
.then(({ data }) => data)
.catch((err) => {
return err;
});
};
How to get actual return value instead of promise
You can use Promise.all to return all the resolved promises:
async function callAPI(i) {
return `API response: ${i}`;
}
async function getResults(arrays) {
const apiCalls = arrays?.map(async (i) => callAPI(i));
return Promise.all(apiCalls);
}
async function callMe() {
const res = await getResults(["1", "2", "3"]);
console.log(res);
}
callMe();
May be const res= await GetResults(["1","2","3"]).toPromise() will work.
https://codesandbox.io/s/login-authentication-usecontext-66t9t?file=/src/index.js
Here how we can pass token in headers for any other pages in codesandbox link. In my code i have action file like this. im getting my response in localstorage.how can i pass my accesstoken here as headers in this page.
import axios from 'axios';
export const upiAction = {
upi,
};
function upi(user) {
return (dispatch) => {
var data = {
upiId: user.upiId,
accountNumber: user.accountNumber,
};
axios
.post('http://localhost:9091/upiidcreation', data
)
.then((res) => {
console.log("res", (res));
const { data } = res;
alert(JSON.stringify(data.responseDesc));
// window.location.pathname = "./homes";
if (data.responseCode === "00") {
window.location.pathname = "./home"
}
})
.catch(err => {
dispatch(setUserUpiError(err, true));
alert("Please Check With details");
});
};
}
export function setUserUpi(showError) {
return {
type: 'SET_UPI_SUCCESS',
showError: showError,
};
}
export function setUserUpiError(error, showError) {
return {
type: 'SET_UPI_ERROR',
error: error,
showError: showError,
};
}
I'm building an App with Next.js, and I need to connect to specific API routes (set up with API Platform) and populate pages with the route's responses.
The API is working fine, but no matter how I try to implement my Axios call inside the getServerSideProps, I always get the same error, ECONNREFUSED, from my Node stack.
I tried to get the data from useEffect() and it's working fine, but I would like to know if there's a way to call it directly in getServerSideProps.
I'm using a Node container for Docker, and the routes are authenticated through a JWT Token (stored in the session and the client cookies for the server-side connection)
Here are is my code:
pages/accounts.js:
export async function getServerSideProps(context) {
const cookies = new Cookies(context.req.headers.cookie)
const adminToken = cookies.get('jwtToken')
const res = await getAllAccounts(adminToken)
return {
props: {
testdata: ''
},
}
}
lib/accounts.js:
import service from '../service'
export const getAllAccounts = async (adminToken) => {
const res = service({ jwtToken : adminToken }).get(`/accounts`).then((response) => {
}).catch((error) => {
console.dir(error)
})
}
HTTP wrapper:
import axios from 'axios';
import jwt_decode from "jwt-decode";
import mockAdapter from 'axios-mock-adapter';
const service = ({ jwtToken = null, store = null, mockURL = null, mockResponse = null, multipart = false } = {}) => {
const options = {};
options.baseURL = process.env.NEXT_PUBLIC_API_URL + '/api';
if(multipart === true) {
options.headers = {
'Content-Type': 'multipart/form-data'
}
} else {
options.headers = {
'Content-Type': 'application/ld+json',
accept: 'application/ld+json'
}
}
const instance = axios.create(options);
instance.interceptors.response.use(response => {
return response;
}, error => {
return Promise.reject(error);
})
if (mockURL !== null && mockResponse !== null) {
let mock = new mockAdapter(instance);
mock.onAny(mockURL).reply(200, mockResponse)
}
return instance;
};
export default service;
Through the error dump in the node stack, I managed to see that the request headers are correct, and the JWT correctly passed through.
Do not use Axios. Just use fetch().
Next.js polyfills fetch() by default on both the client and server, so you can just use it:
In addition to fetch() on the client-side, Next.js polyfills fetch() in the Node.js environment. You can use fetch() in your server code (such as getStaticProps/getServerSideProps) without using polyfills such as isomorphic-unfetch or node-fetch.
Source.
getServerSideProps works well with axios if we return response.data
export const getServerSideProps: GetStaticProps = async ({ params }) => {
const { brandName } = params as IParams;
const brandData = await $host.get(`api/brand/${brandName}`).then(response => response.data);
return {
props: {
brand: brandData,
},
};
};
Your problem is that your async method does not return a promise.
import service from '../service'
export const getAllAccounts = async (adminToken) => {
const res = service({ jwtToken : adminToken }).get(`/accounts`);
return res;
}
In my NextJS begining I followed this tutorial , and I changed fetch to axios in this way:
export const getStaticPaths = async () => {
const res = await fetch('https://jsonplaceholder.typicode.com/users');
const data = await res.json();
const paths = data.map((ninja) => {
return {
params: { id: ninja.id.toString() },
};
});
return {
paths,
fallback: false,
};
};
export const getStaticProps = async (context) => {
const id = context.params.id;
const res = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
const data = await res.json();
return {
props: { ninja: data },
};
};
I applied the change using useEffect()
useEffect(() => {
// const data = await fetch(`https://jsonplaceholder.typicode.com/users/${id}`);
// const res = await data.json();
// setninja(res);
const fetchData = async () => {
const result = await axios(`https://jsonplaceholder.typicode.com/users/${id}`);
setninja(result.data);
};
fetchData();
console.log(data);
}, []);
I hope this info will be useful for you.
I Used Axios in getServerSideProps without any problems.
export const getServerSideProps: GetServerSideProps = async({
params,
res
}) => {
try {
const response = await axios.get(`/api/test`);
return {
props: {
data: response.data
},
}
} catch {
res.statusCode = 404;
return {
props: {}
};
}
};
I'm trying to dispatch more than one axios request inside my method. However, it is not working.
export const getImages = (res) => {
return {
type: actionTypes.GET_IMAGES,
payload: res
}
}
export const loadImages = (imgs, cId) => {
return dispatch => {
let data = [];
for(const i of imgs) {
const id = i.id;
axios.get(`${api.URL}/test/${cId}/files/${id}`)
.then(res => {
if(res.data !== -1) {
const obj = {
name: res.data,
desc: i.caption
};
data(obj);
}
//dispatch(getImages(data));
});
}
console.log('Action:');
console.log(data);
dispatch(getImages(data));
}
}
The console log does not print anything. Do I need to dispatch inside the .then()? If so, how can I run multiples requests before dispatching?
Thanks
I'm getting the error .then() is not a function while attempting to write a React app test w/ jest/enzyme. I don't think the test code is the problem, but for reference, I am following this Redux example.
Here's the code that throws the error:
return store.dispatch(actions.fetchFiles()).then(() => {
expect(store.getActions()).toEqual(expectedActions)
});
My client's codebase uses redux-pack and some conventions that I am not familiar with and I'm having a hard time deciphering where the actual promise is being executed and thus how to chain a "then" function when calling it from my test code as shown in the redux example link posted above.
I've tried to do some debug logging and some variations on the syntax, for example, I attempted to call .then directly on actions.fetchFiles() since I was under the impression that it was the call that actually returned the promise, but it didn't work. I'm getting a tad lost in all this code and questioning where the promise is actually getting executed/returned.
The basic structure of the code is as follows:
A connected Container component that fetches a list of files from an API and then dispatches.
The actual page works fine, but my attempts to test (like the Redux article referenced above) blow up.
Here are what I believe to be the relevant blocks of code in play:
Container component
componentDidMount() {
const { actions } = this.props;
actions.fetchUpload();
}
const mapStateToProps = state => ({
...state.upload,
});
const mapDispatchToProps = dispatch => ({
actions: bindActionCreators({
...uploadActions,
}, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(UploadContainer);
actions.js
import api from '../../core/api';
export const FETCH_FILES = 'upload/fetch-files';
const actions = {
fetchFiles: () => ({
type: FETCH_FILES,
promise: api.upload.getFiles()
})
};
actions.fetchUpload = () => (dispatch) => {
dispatch(actions.fetchFiles());
};
export default actions;
reducer.js
import { handle } from 'redux-pack';
import { FETCH_FILES } from './actions';
const initialState = {
files: []
};
export default (state = initialState, action) => {
switch (action.type) {
case FETCH_FILES:
return handle(state, action, { // this is redux-pack syntax
success: (s, a) => ({ ...s, files: a.payload.files })
});
default:
return state;
}
};
upload.js (api.upload.getFiles)
export default http => ({
getFiles: () => http.get('/file')
});
api.js - uses Axios
import Axios from 'axios';
import { SubmissionError } from 'redux-form';
import queryString from 'query-string';
import upload from './upload';
const axios = Axios.create({
baseURL: '/api/',
withCredentials: true,
paramsSerializer: params => queryString.stringify(params),
});
class HttpError extends Error {
constructor(status, error, errors = {}) {
super(`Http Error: ${status}`);
this.status = status;
this.error = error;
this.errors = errors;
}
getReduxFormError = defaultError => new SubmissionError({
_error: this.error || defaultError,
...this.errors,
});
}
const handleUnauth = (method, url, options) => (err) => {
const { status } = err.response;
if (status === 401) {
return axios.get('/users/refresh')
.then(() => method(url, options))
.catch(() => Promise.reject(err));
}
return Promise.reject(err);
};
const handleHttpError = (err) => {
const { status, data: { message = {} } } = err.response;
if (typeof message === 'string') {
return Promise.reject(new HttpError(status, message));
}
return Promise.reject(new HttpError(status, null, message));
};
const http = {
get: (url, options) => axios.get(url, options)
.then(response => response.data)
.catch(handleUnauth(axios.get, url, options))
.catch(handleHttpError),
post: (url, data, options) => axios.post(url, data, options)
.then(response => response.data)
.catch(handleUnauth(axios.post, url, options))
.catch(handleHttpError),
patch: (url, data, options) => axios.patch(url, data, options)
.then(response => response.data)
.catch(handleUnauth(axios.patch, url, options))
.catch(handleHttpError),
delete: (url, options) => axios.delete(url, options)
.then(response => response.data)
.catch(handleUnauth(axios.delete, url, options))
.catch(handleHttpError),
};
export default {
upload: upload(http)
};
I was expecting the tests to pass because the returned object should match the expected actions, but it errors. Here's the full message:
FAIL src/modules/upload/upload.test.js
Upload module actions › Returns an array of files when calling actions.fetchFiles
TypeError: store.dispatch(...).then is not a function
43 | // );
44 |
> 45 | return store.dispatch(actions.fetchFiles()).then(() => {
|
46 | expect(store.getActions()).toEqual(expectedActions);
47 | });
48 | });
at Object.then (src/modules/upload/upload.test.js:45:52)
When/where is the promise getting returned and how can I chain a .then function like the Redux test example linked above?