Getting responses from two interdependent JSON generates an error [React Hooks] - json

I want to download the data first about the city in which the user is located from ipstack.com and then use this information to generate the weather using openweather.com. However, the following problem occurs during render:
Test.js:20 GET https://api.openweathermap.org/data/2.5/weather?lat=undefined&lon=undefined&units=metric&appid=(MY API KEY) 400 (Bad Request)
The problem is strange because the data I require appears in state eventually:
My code:
import React, { useState, useEffect } from 'react';
const Test = () => {
const [place, setPlace] = useState([]);
const [weather, setWeather] = useState([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
setLoading(false)
fetch(`http://api.ipstack.com/check?access_key=(MY API KEY)`)
.then(result => result.json())
.then(json => {
setPlace([json.latitude, json.longitude, json.region_name])
})
.catch(err => {
console.log("Error " + err);
})
}, [])
useEffect(() => {
fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${place[0]}&lon=${place[1]}&units=metric&appid=(MY API KEY)`)
.then(result => result.json())
.then(json => {
setWeather(json)
})
.catch(err => {
console.log("Error " + err);
setLoading(true);
})
}, [place])
return (
<>
{loading && (
<>
<p>{place[0]}</p>
<p>{place[1]}</p>
<p>{place[2]}</p>
<p>{weather.name}</p>
</>
)}
</>
);
}
export default Test;

I think in the second effect you should fetch data from openweathermap.org only if place array assigned and has correct data. Otherwise on first run you will send invalid data (undefineds instead of positions)

Related

Why am i only seeing "id" in my react app when the fetch get all the data from Strapi?

i am trying Strapi for the first time, and i cant put my raw data into my divs.
On Strapi everything is published, and for the public the get and getOne is checked.
This way i can only see the "id" nothing else.
Any guess?
here is my result from fetch:
Here is the code that i got from the tutorial page:
import { useEffect, useState } from 'react';
import "./App.css"
// Parses the JSON returned by a network request
const parseJSON = (resp) => (resp.json ? resp.json() : resp);
// Checks if a network request came back fine, and throws an error if not
const checkStatus = (resp) => {
if (resp.status >= 200 && resp.status < 300) {
return resp;
}
return parseJSON(resp).then(resp => {
throw resp;
});
};
const App = () => {
const [error, setError] = useState(null);
const [restaurants, setRestaurants] = useState([]);
useEffect(() => {
fetch('http://localhost:1337/api/restaurants', { headers:{ 'Content-Type': 'application/json' },
method: 'GET' })
.then(checkStatus)
.then(parseJSON)
.then(({ data }) => setRestaurants(data))
.catch((error) => setError(error))
}, [])
if (error) {
// Print errors if any
return <div>An error occured: {error.message}</div>;
}
return (
<div>
<div>
{restaurants.map(({ id, name, description }) => (
<div className="black" key={id}>
{name}
{description}
{id}
</div>
))}
</div>
</div>
);
};
export default App;
I figured it out forom Google.
The map section needs to be changed to this:
{restaurants && restaurants.map((restaurant) => (
<div className="black" key={restaurant.id}>
{restaurant.attributes.name}
{restaurant.attributes.description}
{restaurant.id}
{restaurant.attributes.publishedAt}
</div>
))}

Axios Chaining. Cloudinary Upload -> Express -> MSQL save

My second axios call requires const { secure_url } = res.data from the first axios call.
I use the secure url to store in my database with another axios call.
await axios.post(details.upload, formData, {
onUploadProgress: ProgressEvent => {
setUploadP(parseInt(Math.round((ProgressEvent.loaded * 100) / ProgressEvent.total)))
setTimeout(() => setUploadP(0), 3000);
}
})
.then((res) => {
const { secure_url } = res.data;
axios.post('https://foodeii.herokuapp.com/api/insertRecipe', { values: inputValue, userID: props.userID, img: secure_url }).then((response) => {
console.log('Recipe added successfully.')
goBack();
})
})
.catch((err) => {
console.log(err);
})
The second axios call works fine with uploading the data, but I get a timeout, the console log doesn't fire either. My Express insert function is really small so I do not understand why it timeouts.
// INSERT
app.post('/api/insertRecipe', (req, res) => {
const data = req.body.values;
const uID = req.body.userID;
const img = req.body.img;
const sqlInsert = "INSERT INTO recipes (uID, NAME, INGREDIENTS, INSTRUCTIONS, IMAGE) VALUES (?,?,?,?,?)";
db.query(sqlInsert, [uID, data.theName, data.ingredients, data.instructions, img], (err, result) => {
console.log(err);
});
})
My Server runs on Heroku, while the React frontend is on netlify.
The server error is 'code=H12' when the timeout occurs.
Thank you

How to print json api data in reactjs

I'm fetching json api details through GET request and trying to print it. Getting an error:
Error in the console is Uncaught ReferenceError: allUsers is not defined
const Dashboard = ({status, juser}) => {
const [allUsers, setAllUsers] = React.useState([]);
const id = juser.actable_id;
console.log(id); //getting id here as 1
const getAllusers = () => {
axios
.get(`http://localhost:3001/user/${id}`, { withCredentials: true })
.then((response) => {
console.log(response.data);
setAllUsers(response.data);
})
.catch((error) => {
console.log(" error", error);
});
};
React.useEffect(() => {
getAllusers();
}, []);
{allUsers.map((job_seeker, index) => {
return (
<div>
<p>{job_seeker.name}</p>
</div>
);
})}
}
export default Dashboard;
I'm new to react. Any help is appreciatable.
const [state, setState] = React.useState([]);
the state is where your data is located and setState is function to reset the state from anywhere,
so on your code,
const [jobseekers, allUsers] = React.useState([]); // change string to array
jobseekers is the variable where your data is located and allUsers is the function to store data into state.
set data to state using allUsers function,
const getAllusers = () => {
axios
.get(`http://localhost:3001/user/${id}`, { withCredentials: true })
.then((response) => {
allUsers(response.data);
})
.catch((error) => {
console.log(" error", error);
});
};
and map from jobseekers
{jobseekers.map((job_seeker, index) => {
return (
<div>
<p>{job_seeker.name}</p>
</div>
);
})}
Also I would suggest to rename your state and setState as,
const [allUsers, setAllUsers] = React.useState([]);
You didn't pass the value of response to allUsers, instead, you just created a new variable. So change
const allUsers = response.data;
to:
allUsers(response.data)
Besides, you can also improve the way that you have used useState. You have initialized it as an empty string while you'll probably store an array from response in jobseekers. So, initialize it as an empty array.
const [jobseekers, allUsers] = React.useState([]);

Display the value of function in react native

I have this function where i have to return/display the value of results, I'am using react native and couchDB as my database this code is inside of a flatlist. I have tried this one but it is not working. please help me with this one.
vacant (room) {
localNoteDb
.find({
selector: {
status: "vacant",
room_type: room
},
fields: ['_id', 'room_type', 'room_no' ,'price','status','user', 'updated_at', 'hour_status', 'price_per'],
use_index: nameIndex_status.status,
sort: [{status: 'asc'}]
})
.then(result => {
console.log('getListNoteFromDb', result)
let getLenght = result.doc
const results= Object.keys(result).length
console.log('value of results: ', results)
return(
<Text> {Object.keys(result).length}</Text>
);
})
}
Try this way
function Example() {
const [count, setCount] = useState(0);
// Similar to componentDidMount
useEffect(() => {
vacant(...);
});
const vacant (room) {
localNoteDb
.....
.....
.then(result => {
console.log('getListNoteFromDb', result)
let getLenght = result.doc
const results= Object.keys(result).length
setCount(results); <-- This way -->
});
}
return (
<Text> {count}</Text>
);
}

How can I turn a function used in many components into its own component which I can reuse across the app?

I have a fetch request used on multiple pages, and would like to turn it into a component to simply call in whenever it's needed. This is proving to be harder than I thought, and it's bring up a number of issues.
I have tried using the wrappedComponent function but not sure if that's the solution as it's still not working. It's now saying that the fetchPosts class constructor cannot be invoked without new.
const that = this;
fetch ('/testrouter')
.then (response => {
return response.json();
}).then(jsonData => {
that.setState({posts:jsonData})
}).catch(err => {
console.log('Error fetch posts data '+err)
});
}
This is what I want to turn into a component, so that I can just call it by it's name from another one inside componentDidMount. I have tried doing this:
function fetchPosts(WrappedComponent) {
class FetchPosts extends Component {
constructor(props) {
super(props)
this.state = {
posts: []
}
}
fetchAllPosts() {
const that = this;
fetch ('/testrouter')
.then (response => {
return response.json();
}).then(jsonData => {
that.setState({posts:jsonData})
}).catch(err => {
console.log('Error fetch posts data '+err)
});
}
render() {
return (<WrappedComponent
fetchAllPosts = {this.fetchAllPosts})
/>);
}
}
return FetchPosts;
}
export default fetchPosts
Then importing it and calling it with fetchPosts but it's not working.
I was hoping I would be able to create a component, add the code then import the component, but this is not working.
You might want to create a custom hook to do this:
useFetch.jsx
import React, { useState, useEffect } from 'react'
const useFetch = (url) =>
const [state, setState] = useState({ loading: true, data: null, error: null })
useEffect(() => {
fetch(url)
.then(res => res.json())
.then(data => setState(state => ({ ...state, loading: false, data }))
.catch(error => setState(state => ({ ...state, loading: false, error }))
},[])
return state
}
export default useFetch
MyComponent.jsx
import React from 'react'
import useFetch from './useFetch.jsx'
const MyComponent = () => {
const data = useFetch('/testrouter')
return (<>
{ data.loading && "Loading..." }
{ data.error && `There was an error during the fetch: {error.message}` }
{ data.data && <Posts posts={data.data}/> }
</>)
}