How can i change from promise to async/await - reactjs

How I can change the arrow function in my code to async/await syntax in google drive integration.
const listFiles = () => {
setLoading(true)
gapi.client.drive.files
.list({
pageSize: 500,
fields: 'nextPageToken, files(id, name, mimeType, modifiedTime)',
})
.then(function (response) {
setLoading(false)
const res = JSON.parse(response.body);
setDocuments(res.files);
});
};
the another one function I want to add async/await:
const initClient = () => {
setLoading(true)
gapi.client
.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES,
})
.then(
function () {
setConnectStorage(true);
gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
setLoading(false)
},
function (error) {
alert(error)
}
);
};

const listFiles = () => {
setLoading(true)
return new Promise((resolve, reject) => {
gapi.client.drive.files
.list({
pageSize: 500,
fields: 'nextPageToken, files(id, name, mimeType, modifiedTime)',
})
.then(function (response) {
setLoading(false)
const res = JSON.parse(response.body);
resolve(res.files)
});
})
};
const initClient = () => {
setLoading(true)
return new Promise ((resolve, reject) => {
gapi.client
.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES,
})
.then(
function () {
setConnectStorage(true);
// gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);
// updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
resolve({status: gapi.auth2.getAuthInstance().isSignedIn.get()})
setLoading(false)
},
function (error) {
reject({status: false})
}
);
})
};
Then run those functions:
(async () => {
const files = await listFiles()
const status = await initClient()
})()

Related

axios returns "fullfilled" promise

Can someone please tell me why my Axios service function returns this:
The object looks fine in the service function.
Promise {<fulfilled>: {…}}
[[Prototype]]: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Object
Here is the call:
useEffect(() => {
setData(playlistService.getPlaylists);
}, []);
console.log(data);
And the function:
const config = {
headers: {
'Content-Type': 'application/json',
},
withCredentials: true,
};
const getPlaylists = async () => {
try {
const res = await axios.get(`${API_SONGS_URL}/`, config);
console.log('RES ', res);
return res;
} catch (error) {
if (error.response) {
return error.response.data;
}
}
};
this could work
useEffect(() => {
const fetchPlayListAsync = async () => {
const response = await playlistService.getPlaylists();
setData(response)
}
fetchPlayListAsync()
}, []);
you can add appropriate checks of fetched data

react-query customHook refetchOnWindowFocus

I am creating individual hooks using react-query. Where would I add in refetchOnWindowFocus: false ? as it is not currently being read and the data is being re-fetched when returning to the window.
const useFetchOverview = () => {
return useQuery(["userData", { refetchOnWindowFocus: false }],
async () => {
const { data } = await axios({
url: useFetchOverviewUrl,
headers: { ...getHeaders(reduxState) },
method: "get"
});
return data;
});
};
const { isLoading, data: userOverviewData } = useFetchOverview();
this should be third parameter after fuinction:
return useQuery(["userData"],
async () => {
const { data } = await axios({
url: useFetchOverviewUrl,
headers: { ...getHeaders(reduxState) },
method: "get"
});
return data;
}, { refetchOnWindowFocus: false });
ex: useQuery(queryKey, queryFn?, options)
check this for your reference: https://tanstack.com/query/v4/docs/reference/useQuery?from=reactQueryV3&original=https://react-query-v3.tanstack.com/reference/useQuery
OR you can write it for global:
const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
},
},
})

Axios.get not returning any data

I can not get the right info on my API.
i tried this and nothing comes back
const res = () => {
axios.get('https://api.scripture.api.bible/v1/bibles', {
headers: {
'api-key': '5b5d4503884b7a2515e8cee8f4b00746',
},
})
}
Your code works fine, but you are not doing anything with the response. axios.get() returns a Promise, so you need to handle it using .then()
const res = () => {
axios.get("https://api.scripture.api.bible/v1/bibles", {
headers: {
"api-key": "5b5d4503884b7a2515e8cee8f4b00746"
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
};
res();
or make an async function and use async await.
const res = async () => {
try {
const response = await axios.get("https://api.scripture.api.bible/v1/bibles", {
headers: {
"api-key": "5b5d4503884b7a2515e8cee8f4b00746"
}
});
console.log(response);
} catch (error) {
console.log(error);
}
};
res();
Instead of console.logging you can do anything, for example use a callback function:
const res = async (callback, errorCallback) => {
try {
const response = await axios.get("https://api.scripture.api.bible/v1/bibles", {
headers: {
"api-key": "5b5d4503884b7a2515e8cee8f4b00746"
}
});
callback(response);
} catch (error) {
errorCallback(error);
}
};
const onSuccess = result => {
const data = JSON.stringify(result);
alert(data)
};
const onError = error => {
alert(`Ops! An error occured: ${error}`);
};
res(onSuccess, onError);

React Hook , setvariable and print in same useeffect

I want to set name,room variable after axios calling and before socket.join. But SetName() is not working properly, and socket.join() is not receiving new value of Name, Room.
Name and Room value of set after socket.join() is completed, but I wanted is to set Name and Room value before socket.join()
useEffect(() => {
(async () => {
const response = await axios({
method: "get",
url: "https://localhost:5000/",
mode: "cors",
withCredentials: true,
});
const data = await response.data;
await condition_check();
await soc();
function condition_check() {
return new Promise(async (resolve) => {
if (location.state === undefined) {
SetConnected(true);
SetValid(false);
}
if (data.status === "ok" && location.state !== undefined) {
SetName(location.state.Name, () => {
console.log(name);
});
SetRoom(location.state.Room);
SetUserId(location.state.UserId);
SetValid(true);
resolve(console.log("1", name, room));
SetConnected(true);
SetSetup(true);
}
});
}
function soc() {
return new Promise((resolve) => {
if (setup === true) {
socket = socketIOClient.connect(ENDPOINT);
socket.emit(
"Join",
{ Name: name, Room: room, UserId: userid },
(err) => {
if (err) {
alert(err);
}
}
);
console.log("2", name, room);
socket.on("message", ({ Name, Room, message, currenttime }) => {
setMessages((messages) => [...messages, message]);
setSenders((senders) => [...senders, Name]);
setTime((time) => [...time, currenttime]);
resolve(console.log(currenttime));
});
}
});
}
})();
// because `SetRoom` `SetName` is async
useEffect(() => {
(async () => {
const response = await axios({
method: "get",
url: "https://localhost:5000/",
mode: "cors",
withCredentials: true,
});
const data = await response.data;
let NAME;
let ROOM;
await condition_check();
await soc();
function condition_check() {
return new Promise(async (resolve) => {
if (location.state === undefined) {
SetConnected(true);
SetValid(false);
}
if (data.status === "ok" && location.state !== undefined) {
...
NAME = location.state.Name
ROOM = location.state.Room
...
}
});
}
function soc() {
// use local variable `ROOM` and `NAME`
return new Promise((resolve) => {
...
});
}
})();

Branch coverage zero percent in jest

I have written some test cases and everything seems fine except the following one. I am getting zero branch cover for one file. I have googled couple of blog and I came to understand if the statement cab be executed in multiple scenario that call branch coverage. But I don't find my code can be executed in multiple way.
request.js
import axios from 'axios';
export default async (request, httpService = axios) => {
const {
method, url, data, headers,
} = request;
return httpService.request({
method,
url,
headers: Object.assign({}, headers),
data,
});
};
reqeust.test.js
describe('requestServie', () => {
it('should have a valid request object', async () => {
const requestObj = {
method: 'POST',
url: 'http://mock.url',
data: {},
};
const mockRequest = jest.fn(() => Promise.resolve({}));
const httpService = {
request: mockRequest,
};
await request(requestObj, httpService);
expect(mockRequest).toHaveBeenCalledWith({
method: requestObj.method,
url: requestObj.url,
headers: {},
data: requestObj.data,
});
});
it('should return a valid response (empty)', async () => {
const response = {
data: {
},
status: 200,
statusText: 'OK',
headers: {},
config: {},
request: {},
};
const mockRequest = jest.fn(() => Promise.resolve(response));
const httpService = {
request: mockRequest,
};
const res = await request({ url: 'http://mock.url' }, httpService);
expect(res).not.toBe(null);
expect(res).toMatchObject(
{
status: response.status,
},
);
});
});
Edit
rquest.js
export default async (request, httpService = axios) => {
const {
method, url, data, headers,
} = request;
return httpService.request({
method,
url,
headers: Object.assign({}, headers),
data,
}).then(successResponse, (error) => {
throwHttpError(error);
});
};
request.test.js
import HttpError from 'standard-http-error';
import axios from 'axios';
import request, { successResponse, throwHttpError } from './requestService';
describe('requestService', () => {
jest.mock('axios', () => ({
request: jest.fn(() => Promise.resolve({})),
}));
describe('successResponse', () => {
const mockRes = {
status: 9001,
data: {
stuff: 'stuff',
},
};
it('should returns an object with only status and data properties', () => {
const responseKeys = Object.keys(successResponse(mockRes));
expect(responseKeys).toMatchObject(['status', 'data']);
expect(responseKeys.length).toBe(2);
});
it('should map the status of the reponse to the status property', () => {
expect(successResponse(mockRes).status)
.toBe(mockRes.status);
});
it('should map the data of the reponse to the data property', () => {
expect(successResponse(mockRes).data)
.toMatchObject(mockRes.data);
});
it('should have a valid request object', async () => {
const requestObj = {
method: 'POST',
url: 'http://mock.url',
data: {},
headers: {},
};
const mockRequest = jest.fn(() => Promise.resolve({}));
const httpService = {
request: mockRequest,
};
await request(requestObj, httpService);
expect(mockRequest).toHaveBeenCalledWith({
method: requestObj.method,
url: requestObj.url,
headers: {},
data: requestObj.data,
});
});
});
describe('httpThrowError', () => {
const mockErr = {
response: {
status: 9001,
statusText: 'error message goes here',
},
};
it('should map the status of the reponse to the error.status property', () => {
try {
throwHttpError(mockErr);
} catch (e) {
expect(e).not.toBe(null);
expect(e.status).toBe(mockErr.response.status);
expect(e.message).toBe(mockErr.response.statusText);
}
});
it('should map the data of the reponse to the error.data property', () => {
const mockErrWithData = Object.assign({}, mockErr);
mockErrWithData.response.data = {};
try {
throwHttpError(mockErrWithData);
} catch (e) {
expect(e).not.toBe(null);
expect(e.data).toBe(mockErrWithData.response.data);
}
});
});
describe('request', () => {
const testCases = [
['should return error response on server error', 500],
['should return error response on bad request', 400],
['should return error response on unauthorised', 401],
];
testCases.forEach(([testName, errorStatus]) => {
it(testName, async () => {
const errorResponse = {
response: {
status: errorStatus,
},
};
const mockRequest = jest.fn(() => Promise.reject(errorResponse));
const httpService = {
request: mockRequest,
};
try {
await request({ url: 'http://mock.url' }, httpService);
throw new Error('Expected an exception, but none was thrown');
} catch (err) {
expect(err).not.toBe(null);
expect(err).toMatchObject(
new HttpError(errorResponse.response.status,
errorResponse.response.statusText),
);
}
});
});
it('should return an valid response (empty)', async () => {
const response = {
data: {
meta: {},
results: [],
},
status: 200,
statusText: 'OK',
headers: {},
config: {},
request: {},
};
const mockRequest = jest.fn(() => Promise.resolve(response));
const httpService = {
request: mockRequest,
};
const res = await request({ url: 'http://mock.url' }, httpService);
expect(res).not.toBe(null);
expect(res).toMatchObject(
{
status: response.status,
data: response.data,
},
);
});
it('should use axios by default', async () => {
const req = { url: 'http://mock.url', method: 'get' };
await request(req);
expect(axios.request).toHaveBeenCalled();
});
});
});
Error
Updated 15/Nov/18
"jest": "^23.6.0",
import HttpError from 'standard-http-error';
import axios from 'axios';
import request, { successResponse, throwHttpError } from './requestService';
jest.mock('axios', () => ({
request: jest.fn(),
}));
Error
To see what is not covered you can go to coverage/Iconv-report and open index.html. Those are created once you run jest with --coverage option.
It looks like uncovered branch is: httpService = axios. So you need to check if default axios is used.
To cover that you may run request without httpService argument - you can mock axios globally for that, i.e.:
import axios from 'axios';
// note that mock goes before any describe block
jest.mock('axios', () => {
return {
request: jest.fn(() => Promise.resolve({})),
}
});
describe('requestService', () => {
// ... your other tests
it('should use axios by default', async () => {
const opts = { url: 'http://mock.url', method: 'get' };
const res = await request(opts);
expect(axios.request).toHaveBeenCalled();
});
});
Note that jest.mock have some buggy behavior when running inside a spec.

Resources