I have my react frontend which is very basic right now as i just want to retrieve some data from my backend api written in node js which calls and external api
the data is fetched properly to the backend as I have tested it by printing the data. The issue is that my promise on the frontend is never resolved meaning the data is never fetched
frontend code so far:
import "./App.css";
import axios from "axios";
function App() {
const getDataPromise = async () => {
const response = await axios.get(
"http://localhost:8800/api/auth/data"
);
console.log("ACTIVITY RESPONSE = ", response);
//return data;
};
const getActivities = async () => {
const promiseData = await getDataPromise()
// NEVER RESOLVES
console.log("Promise data = ", promiseData);
//getDataPromise().then((res) => console.log("RES = ", res));
//}
};
return (
<div className="App">
<button onClick={getActivities}>Get All Data</button>
</div>
);
}
export default App;
backend section of code with api link replaced with text:
async function getDataPromise() {
const link = `externalAPI`;
const response = await axios.get(link);
console.log("Response = ", response.data[0]);
return response.data[0];
}
router.get("/data", async (req, res) => {
const data = await getDataPromise();
console.log("data = ", data);
return data;
});
Does anyone see my issue why my frontend promise when the getData button is clicked never resolves so the promiseData value is eventually printed
It's on backend side
router.get("/data", async (req, res) => {
const data = await getDataPromise();
console.log("data = ", data);
return data;
});
Try to replace
return data
with
res(data)
You are not calling your async function the right way, try this:
<button onClick={async () => { await getActivities() }}>Get All Data</button>
Hope it helps!
Related
I am facing issues mocking a method which internally makes call to database to fetch data. Please find the code below:
const getData = async (...args) => {
// first call
await db.getData();
// second call
await db.queryData();
return data;
}
const generateResult = async (...args) => {
const data = await getData(...args);
// rest of the code
return result;
}
export ClassTest;
In the test file:
describe(('Verify generateResult') => {
jest.spyOn(generateResult, 'getData').mockImplementation((...args) => {
return data;
});
it('should return result', async () => {
const result = await generateResult(..args);
expect(result).toBeTruthy();
});
});
The getData method makes database calls to retrieve data. Rest of the code just massages the data and returns result. Even though its been mocked the code fails when the database calls are made. I assume that it should get data from mocked implementation and rest of the code should execute. Not sure what is wrong here. Could anyone pls let me know. Do not have a lot of experience writing jest test cases.
thanks
Any chance that you could move the getData method to another module? Then you can mock the getData and the imported version would be the mocked one everywhere. Just an idea.
getData.js
export const getData = async (...args) => {
const data = await Promise.resolve(false);
console.log('original called')
return data;
}
dbUtils.js
import { getData } from './getData'
export const generateResult = async (...args) => {
const data = await getData(...args);
return data;
}
and the test:
import * as getDataUtils from '../getData';
import { generateResult } from '../dbUtils';
it('should return result', async () => {
jest.spyOn(getDataUtils, 'getData').mockResolvedValue(true);
const result = await generateResult();
expect(result).toBeTruthy();
});
I'm new to react-query and I'm trying to move all of my API calls into a new file, out of the useQuery calls.
Unfortunately when I do this all of my data is undefined.
I do see the network calls in the network tab, it just isn't being set properly in useQuery.
Thanks in advance for any help on how to change my code to fix this!
// this works
const { loading, data, error } = useQuery([conf_id], async () => {
const { data } = await axios.get(API_URL + '/event/' + conf_id)
return data
});
// this doesn't work - data is undefined
const axios = require('axios');
const getEventById = async () => {
const { data } = await axios.get(API_URL + '/event/2541' + '?noyear=true');
return data.data;
};
const { loading, data, error } = useQuery('conf_id', getEventById});
// the below variants don't work either
// const { loading, data, error } = useQuery('conf_id', getEventById()});
// const { loading, data, error } = useQuery('conf_id', async () => await getEventById()});
// const { loading, data, error } = useQuery('conf_id', async () => await
// const { data } = getEventById(); return data
// });
An AxiosResponse has a data attribute from which you can access the actual API JSON response.
Like you pointed out, this:
async () => {
const { data } = await axios.get(API_URL + '/event/' + conf_id)
return data
}
Should suffice for the fetching function.
So the final implementation should look like
const axios = require('axios');
const getEventById = async () => {
const { data } = await axios.get(API_URL + '/event/2541' + '?noyear=true');
return data;
};
const { loading, data, error } = useQuery('conf_id', getEventById);
The data you get from the useQuery should be undefined on the first render and once the server responds it will change to whatever the response is.
I am creating a react/ redux app with json fake api server I am trying to add a login and trying to get data from json fake api server, data is showing and all ok , but data is always resulting as a promise and the required data is inside the promise. i tried many ways to distructure but throwing errors , could anyone help me on this,
my axios request
const urlss = "http://localhost:5000/users";
export const userslist = async () => {
const r = await axios.get(urlss);
const data = r.data;
return data;
};
const newout2 = userslist();
const newout = newout2;
console.log(newout);
the place where I am using it
export const login = (credentials) => (dispatch) => {
return new Promise((resolve, reject) => {
const matchingUser =
newout2 &&
newout2.find(({ username }) => username === credentials.username);
if (matchingUser) {
if (matchingUser.password === credentials.password) {
dispatch(setUser(matchingUser));
resolve(matchingUser);
} else {
dispatch(setUser(null));
reject("Password wrong");
}
} else {
dispatch(setUser(null));
reject("No user matching");
}
});
};
i am getting this error
You are using then in your userslist method while awaiting in an async method. drop the then and just use proper await inside an async method.
const urlss = "http://localhost:5000/users";
export const userslist = async () => {
const r = await axios.get(urlss);
const data = r.data;
return data;
};
I'm desperate for help here. I'm trying to test a function with jest but I'm stuck on one thing. When I try to mock the fetch request I get this error:
TypeError: Cannot read property 'json' of undefined
The function I'm trying to test is this:
const updateUI = async () =>{
const res = await fetch('/sentiment');
console.log(res);
try {
console.log(res.data)
const allData = await res.json();
console.log(allData)
document.getElementById("polarity").innerHTML = allData.polarity;
document.getElementById("polarityConfidence").innerHTML = allData.polarity_confidence;
document.getElementById("subjectivity").innerHTML = allData.polarity;
document.getElementById("subjectivityConfidence").innerHTML = allData.polarity_confidence;
return allData;
}catch(error){
console.log('error')
}
};
export { updateUI }
The test I'm trying to run is this:
import "regenerator-runtime/runtime";
import "core-js/stable";
import "fetch-mock"
const fetchMock = require('fetch-mock');
fetchMock.config.sendAsJson = true; \\I've tried with and without this part and I get the same error
import updateUI from './updateUI';
import { isIterable } from "core-js";
describe('updateUI', () => {
it('can fetch', async () => {
fetchMock.get('/sentiment', {polarity: 'polarity', polarity_confidence: 'polarity confidence', subjectivity: 'subjectivity', subjectivity_confidence: 'subjectivity confidence'});
const res = await updateUI('/sentiment');
const allData = await res.json();
expect(allData.polarity).toEqual('polarity');
expect(allData.polarity_confidence).toEqual('polarity confidence');
expect(allData.subjectivity).toEqual('subjectivity');
expect(allData.subjectivity_confidence).toEqual('subjectivity confidence');
})
})
I really have no idea where to go from here. Why won't it get the json object? Is it because my updateUI function calls the json object in the try{} part of the function? If that is the case how do I test it?
I see two problems here
In your test you are passing string like this const res = await updateUI('/sentiment'); which wouldn't matter as updateUI doesn't take any parameter.
In the next line you are doing res.json() which wouldn't work as from your actual method you are only returning response. You in your test you don't need to do .json(). This is the reason you are getting undefined as there is no json function.
This is how I did it. More info can be found on codegrepper
Make sure the Promise.resolve is used well and the mocked and api data both has the same format.
const mockFetchUserData = (data) => {
return global.fetch = jest.fn().mockImplementation(() =>
Promise.resolve({
json: () => data
})
)
}
it('Display empty list of users', async () => {
// Data can be empty array or array of data
await mockFetchUserData([])
await act(async () =>
render(
<Router>
<User />
</Router>
)
})
const findSearchButtonText = screen.getByText('Search') // is search button rendered
expect(findSearchButtonText.type).toBe('submit') // is type submit
}
After I have successfully implemented one of methods to fetch some data and run test
Code:
const fetchData = async (url) => {
const response = await axios.get(url);
const contentType = response.headers['content-type'];
if (typeof response.data === 'object') {
return JSON.stringify(response.data);
}
throw new Error('Content-Type is unrecognized');
};
module.exports = fetchData;
And test:
describe('fetchData', () => {
it('should return json string response data on successful request', async () => {
const responseData = await fetchData(url);
const expectedData = JSON.stringify({ key1: 'value1' });
assert.deepEqual(responseData, expectedData, 'Response data doesn\'t match');
});
However, I wanted to implement scheduling to my method. I implemented in by using node-scheduler npm module.
After my modification
scheduler.scheduleJob({ start: startTime, end: endtTime }, async () => {
const fetchData = async (url) => {
const response = await axios.get(url);
}
Tests are failing immadietly, furthermore I noticed that error log is going continuously, therefore I have to kill test.
Does anyone have an idea why adding simple scheduler makes my error not working? I am using:
Node v.8.11.4
chai-as-promised
nock