How to interpolate an image src in React? - reactjs

I am trying to display a photo from an object I received from an API. I was able to get down to the data information, but the image is not displaying in the displayPhoto function. I was wondering what was wrong with this?
import React, { useState, useEffect } from "react";
import axios from "axios";
// fetch api
// display data
// display more data
export default function App() {
const [data, setData] = useState([]);
const fetchAPI = () => {
axios.get('https://randomuser.me/api')
.then(res => {
// handle success
console.log(res["data"]["results"]);
const indData = (res["data"]["results"]);
const updatedData = [
...data,
...indData
]
setData(updatedData);
// console.log(data)
})
.catch(error => {
// handle error
console.log(error);
})
}
const mapData = (info) => {
const first = (info["name"]["first"])
const last = (info["name"]["last"])
return `${first} ${last}`;
}
const displayPhoto = (info) => {
const picture = (info["picture"]["large"]);
return <img src={picture} />;
}
return (
<>
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<button onClick={fetchAPI} >Fetch API </button>
{data.map((e, idx) => (
<p>{mapData(e, idx)}</p>
{displayPhoto(e)}
))}
</div>
</>
);
}

It looks like you put the wrong src to img tag in displayPhoto function. You should check the path and then render img component with it.
{data.map((e, idx) => (
<div>
<p>{mapData(data, idx)}</p>
<img src={data.rightSrcl} />
</div>
))}

Related

Data is not displaying in react components

I don't understand why my fetched data is not displaying.
Data is fetched properly when i check by console.log() however nothing shows up in my JSX section. Code looks alight too. Anyone have idea what is wrong here?
import React from "react";
import { useEffect, useState } from "react";
import axios from "axios";
export const ConcertLatest = () => {
const [concerts, setConcerts] = useState([]);
useEffect(() => {
const loadConcerts = async () => {
const response = await axios.get("/data/concerts");
const rawData = response.data;
const filteredData = rawData.filter((concert) => {
//let date = new Date(concert.datum);
// let newestDate = new Date("2022-09-29");
return concert.datum >= "2022-09-30";
});
setConcerts(filteredData);
};
loadConcerts();
}, []);
if (!concerts.length) {
return <p>Loading...</p>;
}
console.log(concerts); // getting full populated objects
return (
<div>
<h1>Newest concerts </h1>
<div>
<div className="card">
<img src={concerts.image} style={{ width: 100 }} />
<div className="card-text">
<div>
{concerts.map((concert) => {
(<h1>{concert.name}</h1>), (<h2>{concert.datum}</h2>);
})}
</div>
</div>
</div>
</div>
</div>
);
};
Change syntax of map function, either use return keyword with curly braces or just use round braces without return keyword. Eg
<div>
{concerts.map((concert) => {
return (
<React.Fragment>
(<h1>{concert.name}</h1>), (<h2>{concert.datum}</h2>)
</React.Fragment>
)
})}
</div>
Or
<div>
{concerts.map((concert) => (
<React.Fragment>
(<h1>{concert.name}</h1>), (<h2>{concert.datum}</h2>)
</React.Fragment>
))}
</div>

Issue with API GET response format

I am making a get request to an api and then trying to map over the request. My issue is that the response is changing from data in this usual [{...},{...}] to '[[Object Object][Object Object]]' so that when I try to map over the array, it is throwing an error. I have tried using JSON.stringify() but it does not work. Here is my code:
---- Home.js
import React, { useState, useEffect } from "react";
const Home = () => {
const [tableData, setTableData] = useState([]);
useEffect(() => {
const url =
"https://api.football-data.org/v2/competitions/2021/standings?standingType=HOME";
const fetchItems = async () => {
const apiResult = await fetch(url, {
headers: {
"X-Auth-Token": process.env.REACT_APP_API_KEY,
},
})
.then((res) => res.json())
.catch((err) => console.error(err));
setTableData(apiResult.standings[0].table);
};
fetchItems();
}, []);
return (
<div className="home-container">
<Hero />
<Table data={tableData} />
<Predictions />
<Footer />
</div>
);
};
------ Table.js
import TableList from "./TableList";
const Table = ({ data }) => {
return (
<section className="table" id="table">
<h1 className="table-header">Table</h1>
<div className="table-container">
<TableList data={data} />
</div>
</section>
);
};
--------- TableList.js
import TableCard from "./TableCard";
const TableList = ({ data }) => {
return (
<div className="table-list">
{data.map((index, teamData) => {
return <TableCard key={index} data={teamData} />;
})}
</div>
);
};
If I console log the mapped data, I get '0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20',
instead of the data that I initially receive in the fetch request that is [{position:1, team: {...}, gamesPlayed:9}, {...}].
I have never had this issue before when using a GET request to an API so any and all help is appreciated. Sorry in advance for the poor formatting.

how do I Consume REST API dynamically through component?

I am trying to refactor my component where it takes the data from a remote server as you can see below the mock API response. how can I restructure my component to fully depend on the API response, and fill the component based on their attributes where _name is my heading, and "data"` is our body data to fill the rest table alike
import React, {useState,useEffect} from 'react';
import axios from 'axios';
export default function Demo () {
const [isModalOpen, setModalIsOpen] = useState(false);
const [users, setUsers] = useState([]);
const handleOnClick = async () => {
try {
const { data } = await axios.get('xxxxxxxxxxxxxxx');
setUsers(data);
// Now that the data has been fetched, open the modal
setModalIsOpen(true);
} catch (err) {
console.error("failed", err);
}
};
return (
<div className="container">
<>
{keys.map((key) => (
<div className="col" key={key}>
<div className="row">{key}</div>
{arr[0][key].map((item) => (
<div className="row" key={item._id} onClick={() => handleOnClick(item)}>{item._name}</div>
))}
</div>
))}
</>
{isModalOpen && <Modal onRequestClose={() => setModalIsOpen(false)} data={users}/>}
</div>
);
}
API Response
{
"count":39,
"next":null,
"previous":null,
"results":[
{
"_name":"Collection",
"data":[
{
"_id":"T1560",
"_name":"Archive Data",
"tags":[
"Collection"
],
"subtitle":[
{
"subtitle_id":"T1560.001",
"subtitle_name":"Archive Utility",
"queries":[
],
}
],
"queries":[
],
}
]
}
}

TypeError: data.comments is undefined

I'm fetching two things. An item by id and then the item comments by item id. I when npm start I get
TypeError: data.comments is undefined
But if I comment out
<Comment data={itemComments} />
And then run npm start, the item data loads and if I uncomment the comment tag after the item data has already loaded comments shows until I refresh or reload again, it's only when I try to load them simultaneously I get the error.
Item.js
import React, { useEffect, useState } from "react";
import Comment from "./Comment";
import axios from "axios";
const Item = () => {
const itemId = "6019afbce548e33e7c2f4e56";
const [item, setItem] = useState([]);
const [itemComments, setItemComments] = useState([]);
const fetchData = () => {
const item = `http://localhost:3000/api/v1/items/${itemId}`;
const itemComments = `http://localhost:3000/api/v1/items/${itemId}/comments`;
const getItem = axios.get(item);
const getItemComments = axios.get(itemComments);
axios.all([getItem, getItemComments]).then(
axios.spread((...allData) => {
const allItemData = allData[0].data;
const allItemCommentsData = allData[1].data;
setItem(allItemData);
setItemComments(allItemCommentsData);
})
);
};
useEffect(() => {
fetchData();
}, []);
return (
<div>
<div>
<div>
<h3>{item.title}</h3>
</div>
<div>
<p>Price</p>
<p>${item.price}</p>
</div>
<div>
<h3>Offers & Comments</h3>
<Comment data={itemComments} />
</div>
</div>
</div>
);
};
export default Item;
ItemComments.js
import React from "react";
const Message = (props) => {
const { data } = props;
console.log(data);
return (
<>
{data &&
data.comments.map((comment, i) => (
<div key={i}>
<div>
<div>
<p>{comment.comment}</p>
</div>
</div>
</div>
))}
</>
);
};
export default Message;
After first render react try to access comments inside itemComments when its just an empty array, and you just check if its not undefined in your children component:
{data && data.comments.map((comment, i) => (
<div key={i}>
<div>
<div>
<p>{comment.comment}</p>
</div>
</div>
</div>
))}
so change your initial state to this:
const [itemComments, setItemComments] = useState({comments:[]});
name your comment state by its initial name like this "useState({comments:[]})" and make sure that data.comment is not empty and also try to make fetch data asynchronously and let me know the result, please
const fetchData = async () => {
const item = `http://localhost:3000/api/v1/items/${itemId}`;
const itemComments = `http://localhost:3000/api/v1/items/${itemId}/comments`;
const getItem = await axios.get(item);
const getItemComments = await axios.get(itemComments);
const allData=await axios.all([getItem, getItemComments])
const allItemData= await axios.spread((...allData) => allData[0].data)
const allItemCommentsData= await axios.spread((...allData) => allData[1].data)
setItem(allItemData);
setItemComments(allItemCommentsData);
};

How could I display in my front a back request?

I've created my backend and it works. I tested different Axios requests in order to create a form.
In my React front project, I created a POST axios request, I console.log(response.data) and I got an object with the id, the title and questions.
I am stuck because I don't know how I could display the data of the object in my front.
Here is my front React code:
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import axios from "axios";
const NewForm = () => {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
if (data.length === 0) {
const response = await axios.post(
"https://back-formnest-lereacteur.herokuapp.com/form/create",
{
title: "Your event",
}
);
console.log(response.data);
setData(response.data);
}
};
fetchData();
}, [data]);
return (
I am completely stuck here to display the data of my backend in my front
This is my backend code:
const express = require("express");
const router = express.Router();
const Form = require("../models/Form");
router.post("/form/create", async (req, res) => {
try {
if (req.fields.title) {
const newForm = new Form({
title: req.fields.title,
});
await newForm.save();
return res.json(newForm);
} else {
return res.status(400).json({ error: "Missing parameters" });
}
} catch (e) {
return res.status(400).json({ error: e.message });
}
});
This is my console.log(response.data) I want to display in my front React page:
I edited my code and I got an error:
import React, { useState, useEffect } from "react";
/* import { Link } from "react-router-dom"; */
import axios from "axios";
const NewForm = () => {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
if (data.length === 0) {
const response = await axios.post(
"https://back.herokuapp.com/form/create",
{
title: "Nouveau formulaire",
}
);
console.log(response.data);
setData(response.data);
}
};
fetchData();
}, [data]);
return (
<>
<div>My forms</div>
<div>
{data && (
<>
<p>{data.title}</p>
{data.questions.map((question, index) => (
<div> {question} </div>
))}
</>
)}
</div>
</>
);
};
export default NewForm;
Hi Guys,
I updated my code but I have still an error code (TypeError: Cannot read property 'length' of undefined)
<>
<div>My forms</div>
<div>
{data && (
<>
<p>{data.title}</p>
{data.questions.length &
data.questions.map((question, index) => {
return <p key={index}>{question}</p>;
})}
</>
)}
</div>
</>
I updated again my code, I succeeded only to display the title of my form but I did not succeed to display the data included in my question array. I have a "0" which appears instead of my data. Please help
return (
<>
<div>My forms </div>
<div>
{data && data.questions && (
<>
<div>{data.title} </div>
{data.questions.length &
data.questions.map((question, index) => {
return <p key={index}>{question}</p>;
})}
</>
)}
</div>
</>
I updated again, same error appears:
return (
<>
<div>My forms </div>
<div>
{data &&
data.questions &&
data.questions.length(
<>
<div>{data.title} </div>
{data.questions.map((question, index) => {
return <p key={index}>{question}</p>;
})}
</>
)}
</div>
you've done the hard part!
now just .map over the question array if you want to display them out?
<div>
{data.questions.map((question => (
<div> {question.title} </div>
))}
</div>
I've only done a simple example but of course you can display as much or as little as you want
of course anything in state you can render. so if you want to display title do:
{data.title} wherever pleases you
It looks like your backend responds with an object, so here is how you could go about it.
1) Change your initinal state to undefined like this.
const [data, setData] = useState([]);
to
const [data, setData] = useState(undefined);
Then you can use it in the display like this
return (
<div>
{data && (
<>
<p>{data._id}</p>
<p>{data.title}</p>
{data.question.length && data.question.map((question,idx) => {
// this is assuming that each question is just a string and not an object
return (<p key={idx}>{question}</p>)
})}
</>
)}
</div>
)

Resources