How to import a function into a Vue component? - javascript

I have a js file named axios.js. Inside this file:
import axios from 'axios';
export function axiosGet (url, data, loading) {
axios.get(url, data, loading)
.then((response) => {
loading = false;
data = response.data;
})
.catch(error => console.log(error))
.finally(() => {
loading = true;
})
}
I have a Vue component where I import this function:
import {axiosGet} from '../axios.js'
mounted() {
axiosGet('https://jsonplaceholder.typicode.com/users', this.APIusers, this.isLoading);
}
where APIusers and isLoading are in data.
I get no error but it's not working.
What should I change to make it work?

Your problem is not related to importing function in vue component.
You have to change calling api function to this:
async mounted() {
this.isLoading = true;
const res = await axiosGet("https://jsonplaceholder.typicode.com/users");
if (res) {
this.APIusers = res;
}
this.isLoading = false;
}
and api function:
export async function axiosGet(url) {
try {
const response = await axios.get(url);
return response.data;
} catch (err) {
console.log(err);
}
}
here is working deme: https://codesandbox.io/s/hopeful-murdock-xqpws

Related

React js cannot return data from function

I have two functions, one is a page that calls for data from a function that gets data to and from a server.
The function that gets data to and from a server:
import React, { useEffect, useState, createRef, lazy, useContext } from "react";
import { UserContext } from "./UserContext";
import jwt_decode from "jwt-decode";
import axios from "axios";
export async function getProtectedAsset(url, user, setUser) {
try {
const res = await axios
.post(url, token)
.then((res) => {
console.log(res.data);
return res.data;
})
.catch((err) => {
console.error(err);
});
} catch (error) {
console.log(error);
throw err;
}
}
The code that calls this function:
useEffect(async () => {
try {
let res = await getProtectedAsset(
"http://127.0.0.1:5002/mypage",
user,
setUser
);
console.log(res);
} catch (error) {
console.error(error.message);
}
}, []);
getProtectedAsset will do a successful console.log(res.data); with the data from the server. The calling function that uses useEffect when doing console.log(res); will write undefined to the console.
Why can't I simply return from the function? Obviously the data is received from the server, but for some reason a function cannot return it? I am very confused
Thank you for your help!
You should not use async in useEffect. This is not supported.
I am not sure why you can't use getProtectedAsse(...).then(res=> {}).
But if you want to run getProtectedAsse() synchronously, try like the following instead.
useEffect(() => {
const asyncInternalFunc = async () => {
try {
let res = await getProtectedAsset(
"http://127.0.0.1:5002/mypage",
user,
setUser
);
console.log(res);
return res;
} catch (error) {
console.error(error.message);
}
}
asyncInternalFunc().then();
}, []);
Updated async function to return the response.
export async function getProtectedAsset(url, user, setUser) {
try {
const res = await axios.post(url, token);
return res;
} catch (error) {
console.log(error);
throw err;
}
}

How can i seperate my fetch request to another file in react js

am using react and trying access the promise object which is defined in one file (service file) from another file (class component) .but when am importing the getData to another file ,it gives me undefined.
Can someone help me out in this.
service.js file
export const getData=()=>{
fetch('url', {
method:'Get',
})
.then(data=> {
return data.json()
})
}
component file
import {getData} from '../Service'
console.log(getData()) //gives undefine
you should return data in function getData
service.js file
export const getData=()=>{
return fetch('url', { // add return here
method:'Get',
})
.then(data=> {
return data.json()
})
}
component file
import {getData} from '../Service'
console.log(getData()) //gives undefine
component file
let getFetch = async () => {
const url = "https://jsonplaceholder.typicode.com/todos";
let res = await getRequestData(url);
console.log(res)
}
getFetch();
service.js
const getRequestData = async (url) => {
let resData = await fetch(url)
.then( res => res.json() )
.then( async (result) => {
return result
} ,
(error) => {
return error
});
return resData;
}
export default getRequestData;

React useQuery hook running all the time inside the component

I have a problem where useQuery is always running in my application and I don't why
In my component
import { GET_DATA } from 'apiCalls';
const { loading, error, data } = useQuery('getData', GET_DATA(token));
In my api call
export const GET_DATA = async (token) => {
try {
const res = await axios.get(`${process.env.REACT_APP_SERVER}/api/...`, {
headers: {'auth-token': token},
});
console.log(res);
return res.data;
} catch (err) {
console.log('Error getting data');
return err;
}
}
when I debug my app. The function GET_DATA is always running ALL the time. what is the issue here ?
You must provide the useQuery only the function it wants to run, you must not call it inside useQuery. Provide the token to GET_DATA this way:
EDIT
As #tkdodo said we don't need to use the async function.
const { loading, error, data } = useQuery('getData', ()=>{
return GET_DATA(token);
});
The first solution I provided was this:
const { loading, error, data } = useQuery('getData', async()=>{
const data = await GET_DATA(token);
return data;
});
The root cause is the same as in React-Query, useQuery returns undefined only after loading is complete
The queryFn needs to be a function that returns a promise. GET_DATA does that. But by doing
GET_DATA(token) you directly invoke the function. So you’ll likely want:
() => GET_DATA(token) instead.
Try the following:
// apiCalls.js
export const getData = async (token) => {
try {
const res = await axios.get(`${process.env.REACT_APP_SERVER}/api/...`, {
headers: {'auth-token': token},
});
return res.data;
} catch (err) {
console.log('Error getting data');
return err;
}
// Component.js
import { getData } from 'apiCalls';
function Component(){
const { loading, error, data } = useQuery(
'getData',
()=>GET_DATA(token)
);
return (
<div>...</div>
)
}
useQuery should run in the component and the second parameter should not be a promise, but a function that returns a promise.

I'm writing a test case in React related to authentication(using axios), But I am stuck because the test case is not passing

Existing code:
loginUser.js:
import { getUserDetails } from '../api/userDetails';
import { mapApiObjectToModel } from '../mapper/userProfileMapper';
import axios from 'axios';
export const getLoggedInUserDetails = async () => {
axios
.get('/api/getUserDetails')
.then(response => {
return mapApiObjectToModel(response);
})
.catch(err => {
console.log('error==', err);
});
};
userProfileMapper.js:
export const mapApiObjectToModel = inputObj => {
const outputObj = {};
const authorizedRoles = ['Admin'];
if (inputObj) {
outputObj.fullName = '';
if (inputObj.data) {
outputObj.fullName = inputObj.data.data;
}
outputObj.role = 'Admin';
outputObj.isAuthorized = authorizedRoles.includes(outputObj.role);
}
console.log('outputObj', outputObj);
return outputObj;
};
loginUser.test.js:
import axios from 'axios';
import getLoggedInUserDetails from '../../action/loginUser';
jest.mock('axios');
describe('routes using memory router', () => {
it('Get Admin message', async () => {
const data = 'Admin';
axios.get.mockImplementationOnce(() => Promise.resolve(data));
console.log(data);
await expect(getLoggedInUserDetails()).resolves.toEqual(data);
expect(axios.get).toHaveBeenCalledWith('/api/getUserDetails');
});
it('fetches erroneously data from an API', async () => {
const errorMessage = 'Network Error';
axios.get.mockImplementationOnce(() => Promise.reject(new Error(errorMessage)));
await expect(getLoggedInUserDetails()).rejects.toThrow(errorMessage);
});
});
I'm really new to all these, so any assistance would be appreciated. Even any suggestions on TDD for userProfileMapper.js would be appreciated :)
The mapApiObjectToModel returns an object like,
{
role: 'ADMIN',
isAuthorized: true
}
However, in your test, you are expecting it to be equal to a string 'Admin'
const data = 'Admin';
...
await expect(getLoggedInUserDetails()).resolves.toEqual(data); // Note that you have initialize data to 'Admin'
Try changing data to be an object, like,
const data = {
role: 'Admin',
isAuthorized: true
};
...
await expect(getLoggedInUserDetails()).resolves.toEqual(data);
Updated: loginUser.js:
import { getUserDetails } from '../api/userDetails';
import { mapApiObjectToModel } from '../mapper/userProfileMapper';
import axios from 'axios';
export const getLoggedInUserDetails = () => {
return axios
.get('/api/getUserDetails')
.then(response => {
return mapApiObjectToModel(response);
})
.catch(err => {
console.log('error==', err);
throw err;
});
};
You function getLoggedInUserDetails had following issues,
You were not returning the promise from the function.
You don't need async here as you are accessing expect(Promise).resolves in your test file loginUser.test.js:.
You need to throw err from catch block, if you want to test the rejection of promise or remove the catch block.
I have updated following items to the function getLoggedInUserDetails,
removed the async from export const getLoggedInUserDetails = async () => {
returned promise from axios.get('/api/getUserDetails')
added throw err to catch block
You should not mix usage of Promise.then and async/await for more information on the difference between them check here and here

Vue.js calling an async function from external js file

I am trying to create a .js file where I have a couple of my async calls.
I set up the file, but am not getting any results when I call my method.
This is all new to me to call from a .js file, so not sure what I am doing wrong.
Here is my inventory.js fileimport axios from "axios";
let getInventories = async () => {
const result = await axios
.get("/inventories")
.catch((error) => console.log(error));
// this.inventoryArray = result.data;
}
export {getInventories}
Here is the call from my Inventory.vue file
import axios from "axios";
import { bus } from "../app";
import {getInventories} from './inventory';
export default {
mounted() {
let temp = getInventories();
debugger;
},
}
temp not returning anything. I add await in from of getInventories but get an error
You're missing to return the result :
let getInventories = async () => {
try{
const result = await axios
.get("/inventories")
return result.data;
} catch(error){
console.log(error);
return null;
};
}
export {getInventories}

Categories