why am I getting an error in fetching data here? - javascript

I have this for saving fetched data in state:
import React, {useState, useEffect, createContext} from 'react';
import { getLocation } from '../api';
export const LocationContext = createContext();
const LocatonContextProvider = (props) => {
const [location, setLocation] = useState({})
useEffect(() => {
const fetchAPI = async () => {
setLocation(await getLocation());
}
fetchAPI();
}, [])
return (
<LocationContext.Provider value={location}>
{props.children}
</LocationContext.Provider>
);
};
export default LocatonContextProvider;
and this for saving weather data
import React, {useState, useEffect, createContext, useContext} from
'react';
//api
import { getWeather } from '../services/api';
//Context
import { LocationContext } from '../contexts/LocationContextProvider';
export const WeatherContext = createContext()
const WeatherContextProvider = ({children}) => {
const location = useContext(LocationContext);
const lat = location.lat;
const lon = location.lon;
const [weather, setWeather] = useState({});
useEffect(() => {
const fetchAPI = async () => {
setWeather(await getWeather(lat,lon));
}
fetchAPI();
}, [lat, lon])
return (
<WeatherContext.Provider value={weather}>
{children}
</WeatherContext.Provider>
);
};
export default WeatherContextProvider;
and here is the axios request:
import axios from "axios";
const getLocation = async () => {
const LOCATION_URL = 'http://ip-api.com/json/?fields=country,city,lat,lon,timezone';
const response = await axios.get(LOCATION_URL);
return response.data;
}
const getWeather = async (lat, lon) => {
const WEATHER_URL = `https://api.openweathermap.org/data/2.5/weather?
lat=${lat}&lon=${lon}&appid=bac9f71264248603c36f011a991ec5f6`;
const response = await axios.get(WEATHER_URL)
return response.data;
}
export {getLocation, getWeather};
When I refresh the page, I get an 400 error and after that I get the data, I don't know why the error occurs

useEffect(() => {
const fetchAPI = async () => {
setWeather(await getWeather(lat,lon));
}
if (lat && lon) {
fetchAPI();
}
}, [lat, lon])

Related

Name is not saving to my localStorage (React Context)

I created a provider of a context where I store a name in an array that should be saved in my localstorage, but for some reason it is not saving
import React, { useEffect, useState } from "react";
import AuthContext from "./AuthContext";
const AuthProvider = ({ children }) => {
const [name, setName] = useState(() => {
const dataStorage = localStorage.getItem('name');
if (dataStorage) {
return JSON.parse(dataStorage);
} else {
return [];
}
});
useEffect(() => {
localStorage.setItem('name', JSON.stringify(name));
}, [name]);
const addName = (name) => {
setName(name);
}
return (
<AuthContext.Provider value={{ name: name, addName }}>
{children}
</AuthContext.Provider>
)
}
export default AuthProvider;
context
import { createContext } from 'react';
const AuthContext = createContext({
name: [],
addName: () => {},
});
export default AuthContext;
I'm wanting to send my name from this useState on this page to the name array inside my context and store it in localStorage
const Home = () => {
const navigate = useNavigate();
const { addName } = useContext(AuthContext);
const [name, setName] = useState('');
const [key, setKey] = useState('');
const handleEnterChat = async () => {
if (name) {
const enterName = await addName(name);
navigate('/chat')
} else {
console.log('Fill the info')
}
}
export default Home;
My handle works by sending the user to the /chat route, but it doesn't store the name in localStorage. I would like to know what is wrong with this code

Why does it make a mistake?

The code below is not working. It doesn't see the apikey in parentheses.I couldn't understand what I had to do here. Is it a problem with the hooks structure?
import React, { useEffect } from 'react';
import MovieListing from "../MovieListing/MovieListing";
import movieApi from "../../common/apis/movieApi";
import { APIKey } from "../../common/apis/MovieApiKey"; //the program does not see this
import "./Home.scss";
import { useDispatch } from 'react-redux';
import { addMovies } from '../../features/movies/movieSlice';
const Home = () => {
const dispatch = useDispatch();
useEffect(() => {
const movieText = "Harry";
const fetchMovies = async () => {
const response = await movieApi.get('?apiKey=${APIKey}&s=${movieText}&type=movie')
.catch((err) => { console.log("Err :", err) });
dispatch(addMovies)(response.data); //api key does not see this
};
fetchMovies();
}, []);
return (
<div>
<div className='banner-img'></div>
<MovieListing />
</div>
);
};
export default Home;

I am trying to history.push but its always undefined on react

I am trying to history.push but its always undefined.
import React, { useEffect, useState } from "react";
import * as Firebase from "firebase/app";
import "firebase/auth";
import DBAPI from "./database/database-api"
import DBName from "./database/database-name"
import { useHistory } from "react-router-dom";
export const UserContext = React.createContext();
export const UserProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState(null);
const [isAdmin, setIsAdmin] = useState(null);
const [isVendor, setIsVendor] = useState(null);
const [pending, setPending] = useState(true);
let history = useHistory();
useEffect(() => {
Firebase.auth().onAuthStateChanged(async (user) => {
if (user != null) {
setCurrentUser(user)
let response = await Promise.all([
DBAPI.checkUserExist(DBName.admin, user.uid),
DBAPI.checkUserExist(DBName.vendor, user.uid)
]);
console.log(response[0].data)
console.log(response[1].data)
if (response[0].data) setIsAdmin(true) // admin
if (response[1].data) setIsVendor(true) // vendor
history.push(`${process.env.PUBLIC_URL}/products`)
} else {
setIsVendor(false)
setIsAdmin(false)
}
setPending(false)
});
}, []);
if(pending){
return <>Loading...</>
}
return (
<UserContext.Provider
value={{
currentUser,
isAdmin,
isVendor
}}
>
{children}
</UserContext.Provider>
);
};
The code looks ok. Just make sure your component is wrapped in a <Router> context.

Console log showing more than expected while using React Hooks

I am trying to fetch Data from an Api. I am getting the required result but when I try to console log it , it is console logging 4 times.
This is my app.js where I am using the fetchData.
import React, {useEffect, useState} from 'react';
import styles from './App.modules.css';
import {Header, Cards, Footer, Map, Table, Statecards} from './components/exports';
import {fetchData} from './api';
function App() {
const [data, setData] = useState({});
useEffect(() => {
const settingData = async () => {
const data = await fetchData();
setData(data);
}
settingData();
}, []);
console.log(data);
return <div className = {styles.container}>
<Header />
</div>
;
}
export default App;
This is the fetchData function
import axios from 'axios';
const url = 'https://api.covid19india.org/data.json';
export const fetchData = async () => {
try{
const response = await axios.get(url);
return response;
}
catch(err){
console.log(err);
}
};
The console.log in the app.js is giving 4 console logs as below
I am not being able to figure out what's wrong.
const settingData = async () => {
const data = await fetchData();
setData(data);
}
useEffect(() => {
settingData();
}, []);
try this one.

How can I mock return data from a custom hook in React/Jest?

I have a custom hook called useFetch which simply fetches data and returns it, in my component test I want to just mock this hook to return some fake data, how can I go about doing this?
import React, { useEffect, useState } from 'react';
export const useFetch = (url: string) => {
const [data, setData] = useState();
useEffect(() => {
const fetchData = async () => {
try {
const res = await fetch(url);
const json = await res.json();
setData(json);
} catch (error) {
console.log(error);
}
};
fetchData();
}, [url]);
return data;
};
const App = () => {
const config = useFetch(`/api/url`);
return (
<div></div>
);
};
export default App;
Is there anyway I can mock useFetch so that const config is set to some dummy data in my Jest test?
I Will suggest to put your hook in separate file lets say useFetch.js conntains
import { useEffect, useState } from "react";
export const useFetch = (url: string) => {
const [data, setData] = useState();
useEffect(() => {
const fetchData = async () => {
try {
const res = await fetch(url);
const json = await res.json();
setData(json);
} catch (error) {
console.log(error);
}
};
fetchData();
}, [url]);
return data;
};
Keeping your app component file like follows
import React from "react";
import { useFetch } from "./useFetch";
const App = () => {
const config = useFetch(`/api/url`);
return (
<div></div>
);
};
export default App;
with above split you can easily mock your hook, example test file as follows
import React from "react";
import { render } from "#testing-library/react";
import App from "./App";
// mock config
const mockConfig = {
data: "mock data"
};
// this will mock complete file, we have provided mock implementation
// for useFetch function
jest.mock("./useFetch", () => ({
useFetch: () => mockConfig
}));
test("should render with mock useFetch", () => {
const { getByText } = render(<App />);
// test logic goes here
});
Assuming all the files are in same directory.
You could try to mock the fetch library.
In the test setup:
global.fetch = jest.fn()
And then in your test:
global.fetch.mockResolvedValue({ json: () => ({ data: "" })})

Categories