I'm trying to use Spotify API and to move into the Arrays.
const App = () => {
const [isLoading, setIsLoading] = useState(true);
const [dataSource, setDataSource] = useState();
useEffect(() => {
return fetch("https://api.spotify.com/v1/me/albums?offset=0&limit=5", {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization:
"Bearer AUTH CODE "
}
})
.then(response => response.json())
.then(responseJson => {
setIsLoading(false);
// console.log(responseJson);
// let result = Object.values(responseJson); // if I want to convert it in array
let result = responseJson
setDataSource(result);
});
}, []);
console.log(dataSource);
and I get an object
{href: "https://api.spotify.com/v1/me/albums?o`enter code here`ffset=0&limit=5", items: Array(5) ...}
I would like to go into items but when i do
console.log(dataSource.items);
or
console.log(dataSource.items[1]);
I get
Cannot read property 'items' of undefined
Any idea?
Where is my mistake?
The dataSource state is by default undefined, you need to change the default value to have items property. The fetch is handling the then asynchronously so the data will arrive few milliseconds later and in that time the code tries to access items property which is missing.
You can try to initialize differently, like the following:
const [dataSource, setDataSource] = useState({ items: [] });
I hope this helps!
Related
I'm using antd with react to upload an image to each of my facilities.
The uploading is working, but I can't seem to get the preview from the previous image to show up where it should, by pulling the existing image from the database.
What happens is that it will only show the new image, after it has been uploaded via drag and drop but not the previous one stored in the database. I'm pulling the url of the previous image with the const "testing" and I can log it and it will show inside the console but it will not show when I use it in the setFileList const. What am I missing here?
export function FacilityUpdate() {
const navigate = useNavigate()
const { id } = useParams()
const [facility, setFacility] = useState(null)
const accessToken = useSelector((state) => state.tokens.value.accessToken);
const [loadingFacility, setLoadingFacility] = useState(false)
const [loading, setLoading] = useState(false)
const dispatch = useDispatch();
useEffect(() => {
if (facility && !facility.is_owner) {
navigate('/facilities')
}
return () => null
})
useEffect(() => {
setLoadingFacility(true)
function fetchFacility() {
axios.get(API.facilities.retrieve(id), {
headers: {
"Authorization": `Bearer ${accessToken}`
},
withCredentials: true,
})
.then(res => {
setFacility(res.data)
})
.finally(() => {
setLoadingFacility(false)
})
}
fetchFacility()
return () => null
}, [id, accessToken])
const testing = facility && (facility.mainimage)
console.log(testing)
const [fileList, setFileList] = useState([
{
uid: '-1',
name: testing,
status: 'done',
//This is where the preview image gets loaded from the database:
url: testing,
},
]);
const onUploadDraggerChange = ({ fileList: newFileList, file: resp }) => {
setFileList(newFileList);
if (!resp || !resp.response || !resp.response.mainimage) {
return;
}
message.success("Updated facility picture")
};
const uploadDraggerrops = {
name: 'mainimage',
action: API.facilities.update(id),
method: 'PATCH',
listType: "picture-card",
maxCount: 1,
onChange: onUploadDraggerChange,
fileList: fileList,
headers: {
"Authorization": `Bearer ${accessToken}`
},
withCredentials: true,
};
The problem with your code might come from this line on onUploadDraggerChange:
setFileList(newFileList);
Before updating the state of fileList, fileList is an array with an element that contains that previous picture. When you call onUploadDraggerChange you are erasing the stored content and replacing it with the new one. Maybe you want to push it to add to the array?
setFileList([...fileList, newFileList]);
This way, the first element is the one fetched and the consequent ones from the draggerUpload.
Any case, it looks like the structure of your state should look like
const [facility, setFacility] = useState(null)
const [fileList, setFileList] = useState([]);
useEffect(() => {
if (facility && !facility.is_owner) {
navigate('/facilities')
}
return () => null
})
useEffect(() => {
setLoadingFacility(true)
function fetchFacility() {
axios.get(API.facilities.retrieve(id), {
headers: {"Authorization": `Bearer ${accessToken}`},
withCredentials: true,
})
.then(res => {
setFacility(res.data)
res && (res.mainimage) {
setFileList([...filelist, {
uid: 'some-random-id',
name: testing,
status: 'done',Ï
url: res.mainimage
}])
})
.finally(() => {
setLoadingFacility(false)
})
}
fetchFacility()
return () => null
}, [id, accessToken])
Given url Data==> need to get only Karnataka state details
[{"id":1,"title":"TELANGANA","image":"url","stateCode":"TS"},{"id":4,"title":"TAMILNADU","image":"url","stateCode":"TN"},{"id":3,"title":"KARNATAKA","image":"url","stateCode":"KN"},{"id":2,"title":"ANDHRA","image":"url","stateCode":"AP"}]
Here code to get data===>
const [states, setStates] = useState([]);
useEffect(() => {
handleGetStates()
}, []);
const handleGetStates = async () => {
let values = {
url: `url`,
method: 'get',
}
try {
const response = await axios(values)
setStates(response.data)
console.log(response.data,'response');
} catch (error) {
// handle error
console.log(error);
}
};
You can filter on the array returned from the API:
...
const response = await axios( values );
setStates( response.data.filter(state => state.title === 'KARNATAKA' );
// result: [ {"id":3,"title":"KARNATAKA","image":"url","stateCode":"KN"} ]
...
This will loop through the response and only keep states that have a title of "KARNATAKA"
You can use an array filter method
const {data} = await axios(values);
const result = data?.filter(el=>el.stateCode==='KN')
I have the following state and function
const [obj, setObj] = useState([])
const getData = async (e) => {
e.preventDefault();
const text = e.target.input.value;
const payload = {
input: text,
};
const response = await fetch(process.env.API_LINK, {
body: JSON.stringify(payload),
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
"Content-Type": "application/json",
},
method: "POST",
});
if (response.ok) {
const data = await response.json();
const output = data.choices[0].text;
setObj(obj => [...obj, {input: text, output: output}])
}
};
return (
<form onSubmit={(e) => getData(e)}>
<input name="input"/>
</form>
)
The issue is that when the state obj is empty it doesn't get updated when the function first runs, it has to be run twice for obj to be updated. The response from the API and everything else is fine.
Can you try changing setObj call to :
setObj([...obj, {input: text, output: output}])
What you pass to setObj is a function rather than a state obj. It needs to be called hence the changes shows the second time onwards.
I am the new guy in the JS and reactJS.
I want to get info from API to an array. I made API that show all the info from my DB.
It looks like this :
const [tempNew, setTempNew] = useState([]);
const getAllWeatherCelsius = () => {
fetch('http://localhost:5000/weather')
.then(response => {
return response.json();
})
.then((jsonData) => {
let tmpArray = [];
for (var i = 0; i < jsonData.length; i++) {
tmpArray.push(jsonData.dayCelsius[i]) <---- here is the error
}
setTempNew(tmpArray);
})
}
Im want to collect all values from "dayCelsius" line into array.
What i need to change in this code ? Thank you :)
Can you provide more info about the error? But You can try using the map function like
const tmpArray = jsonData.map(r => r.dayCelsius);
You can use map function to return the dayCelsius value of each element and store them in the tmpArray.
let tmpArray = jsonData.map((el, i) => el.dayCelsius);
So, what I understand is that you are facing difficulty in just getting the dayCelsius value from the array of objects you fetch from your API.
It is difficult to make out what the problem is as more info about the error is required to see what is going wrong.
What I have done differently here is instead of the for-loop and jsonData.dayCelsius[i], I have used data.map((r,e) => r.dayCelsius).
const [temp, setTemp] = useState([]);
const getAllWeatherCelsius = () => {
fetch('http://localhost:5000/weather', {
method: "GET",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
}
})
.then(response => {
return response.json();
})
.then((data) => {
const tempArray = data.map((r,e) => r.dayCelsius);
setTemp(tempArray);
})
.catch(err => console.log(err));
}
I hope it helps you, have a good day :)
I am trying to delete items from my MERN stack app using fetch and I have successfully deleted the item in the database. However, I cannot figure out how to delete the item from state when I click the delete button. I am using the ID of the item (groupID) to delete from the database, and I'm trying to use that to delete from state as well. Right now when clicking the button the item deletes but does not disappear until i reload the page. Here is my code:
const [value, setValue] = useState("");
const [groupsState, setGroups] = useState({});
const [loading, setLoading] = useState(true);
const { isDarkMode } = useContext(ThemeContext);
const { token } = useContext(LoggedInContext);
const handleClick = (groupId) => {
function removeGroup(groupId) {
setGroups(groupsState.filter(el => el !== groupId));
}
fetch("http://localhost:8181/groups/" + groupId, {
headers: {
"Content-Type": "application/json",
Token: token
},
method: "DELETE"
})
.then((res) => {
return res.json();
})
.then((data) => {
console.log(data.data)
removeGroup(groupId);
})
};
If you're set on removing it in JavaScript, you'll just need to specify the id key in your filter
setGroups(groupsState.filter(el => el.id !== groupId));
That's assuming it's called id, otherwise just change it to what your id key is.