useEffect(async () =>
{
const fetchData = async () =>
{
const result = await axios("")
setposts(result.data)
}
fetchData();
}, [])
Rendering :
posts.map(post => <li>{post.name}</li>)
Json File :
[
{
"id": 1,
"vendor": "Gap",
"name": "Men's Pullover Sweatshirt",
"image_src": ["https://cdn.shopify.com/s/files/1/0455/2176/4502/files/Sweater_0.jpg?v=1603266982"],
"price": "74",
"tag": "T-shirt",
"compare_at_price": "200",
"options": [
{
"id": "1010",
"name": "Size",
"value": "US 8"
}, {
"id": "1011",
"name": "Size",
"value": "US 9"
}, {
"id": "1012",
"name": "Size",
"value": "US 10"
}, {
"id": "1013",
"name": "Size",
"value": "US 11"
}, {
"id": "1014",
"name": "Size",
"value": "US 13"
}
]
},
im facing issue to retrieve the data from json file Like i m not able render the data so please help over this
Getting error while mapping the data
im facing issue to retrieve the data from json file Like i m not able render the data so please help over this
useEffect(() =>
{
const fetchData = async () =>
{
const result = await axios.get("https://cdn.shopify.com/s/files/1/0455/2176/4502/files/products.json")
setposts(result.data)
}
fetchData();
}, [])
posts?.map(post => <li>{post.name}</li>)
The issue lies with this file: https://cdn.shopify.com/s/files/1/0455/2176/4502/files/products.json
It returns a an invalid JSON string. So when your axios gets its contents, it sets your posts variable to a simple string, which obviously cannot be mapped through. Hence the error.
The reason axios does not convert it into a JS array is because the file does not contain valid JSON to parse.
The reason the JSON in the file is invalid is because it has a trailing comma after the very last object of the array. See image:
The reason this isn't working for you is, result.data is a string, not an array.
You'll have to convert result.data to array with JSON.parse
Also, the json you're using has a training comma which has to be handled for JSON.parse to work
following code worked for me:
export default function App() {
const [posts, setposts] = useState([]);
useEffect(async () => {
const fetchData = async () => {
const result = await axios.get(
"https://cdn.shopify.com/s/files/1/0455/2176/4502/files/products.json"
);
let regex = /\,(?!\s*?[\{\[\"\'\w])/g;
let correct = result.data.replace(regex, "");
setposts(JSON.parse(correct));
};
fetchData();
}, []);
return (
<div className="App">
{posts.map((post) => (
<li>{post.name}</li>
))}
</div>
);
}
Related
UPDATE: I have deployed the site for more context you can view it here https://conundrum-quest-rw-rebuild-web.onrender.com/
the public repo is here
https://github.com/wispyco/conundrum-quest-rw-rebuild
Note: the data on the live site is different but the initial load is loading the hero's on the wrong cards, you can compare the quest with subsequent heros on the home page and the returned data from my function below, you can scroll down to see the rendered cards.
You can see that if you click on a card it shows the correct heros on the single page.
I have the following quests data structure that I am looping through in a separate function and running a fetch to request some profile images from twitter.
[
{
"__typename": "Quest",
"id": 5,
"name": "How do we solve mental health related issues?",
"userId": 17,
"heros": [
{
"__typename": "Hero",
"name": "Anders Kitson",
"twitter": "anderskitson"
},
{
"__typename": "Hero",
"name": "ders",
"twitter": "derz_O"
}
]
},
{
"__typename": "Quest",
"id": 6,
"name": "How do we create a world where North Korea participates and collaborates with the rest of the World?",
"userId": 17,
"heros": [
{
"__typename": "Hero",
"name": "Crypto Dude",
"twitter": "phunk2243"
}
]
}
]
Here is my custom hook
const twitter = useFetchTwitterMultipleQuests(quests)
export const useFetchTwitterMultipleQuests = (twitterProfileManyQuests) => {
const [twitter, setTwitter] = useState([])
useEffect(() => {
twitterProfileManyQuests.forEach(async (twitterProfileMany, i) => {
const woop = twitterProfileMany.heros.map(async (twitterProfile) => {
const test = fetch(
`${window.location.origin}/.redwood/functions/twitter`,
{
method: 'POST',
body: JSON.stringify({ twitter: twitterProfile.twitter }),
}
)
.then(function (response) {
// The response is a Response instance.
// You parse the data into a useable format using `.json()`
console.log('test')
return response.json()
})
.then(function (data) {
return data.data.resultAwaited.data
})
const go = await test
return go
})
const june = await Promise.all(woop)
setTwitter((prevState) => {
return [...prevState, june]
})
})
}, [twitterProfileManyQuests])
const reversedTwitter = twitter.reverse()
return reversedTwitter
}
The problem is the reversedTwitter or twitter variable in the end sometimes is in the correct reversed order and sometimes not reversed, and I can't figure out why.
This is the correct order result
[
[
{
"username": "anderskitson",
"profile_image_url": "https://pbs.twimg.com/profile_images/1428160652237889539/I7ZiM_g8_normal.jpg",
"name": "▲nders on a quest 🜸 to see myself 🪞",
"id": "4633808432"
},
{
"profile_image_url": "https://pbs.twimg.com/profile_images/1496985668043436033/NoyLrUys_normal.jpg",
"name": "ders.eth",
"id": "1389695824934834181",
"username": "derz_O"
}
],
[
{
"username": "phunk2243",
"profile_image_url": "https://pbs.twimg.com/profile_images/1536485988767350784/cfP_sPSC_normal.jpg",
"name": "9999999333 (🅱️uilding 35 Phunks) 🔜",
"id": "1355005208259133442"
}
]
]
This is the incorrect order result
[
[
{
"name": "9999999333 (🅱️uilding 35 Phunks) 🔜",
"profile_image_url": "https://pbs.twimg.com/profile_images/1536485988767350784/cfP_sPSC_normal.jpg",
"username": "phunk2243",
"id": "1355005208259133442"
}
],
[
{
"username": "anderskitson",
"profile_image_url": "https://pbs.twimg.com/profile_images/1428160652237889539/I7ZiM_g8_normal.jpg",
"name": "▲nders on a quest 🜸 to see myself 🪞",
"id": "4633808432"
},
{
"username": "derz_O",
"profile_image_url": "https://pbs.twimg.com/profile_images/1496985668043436033/NoyLrUys_normal.jpg",
"name": "ders.eth",
"id": "1389695824934834181"
}
]
]
The reason this matters is how I am rendering the data. I am rendering a Quest from the quests data, then mapping over the heros in a quest which correspond to the twitter profiles.
See Here
{quests.map((quest, i) => (
<QuestCard key={quest.id}>
<Link to={routes.quest({ id: quest.id })} key={quest.id}>
<div>
<h3>{truncate(quest.name)}</h3>
{quest.heros.map((hero, index) => (
<React.Fragment key={hero.id}>
{twitter.length > 0 && twitter[i] && (
<span>
{hero.name}
<p>{twitter[i][index]?.name}</p>
<img
key={i}
src={twitter[i][index]?.profile_image_url}
alt={twitter[i][index]?.name}
/>
</span>
)}
</React.Fragment>
))}
</div>
</Link>
<div className="clear" />
</QuestCard>
))}
Any help would be greatly appreciated, most of what I have done works, but after about three refreshes the ordering breaks. Thanks
Fixed by using a custom service and a custom sdl in redwood instead of using a function and having to create a custom hook for rendering. This was recommended by the RW team from this article
https://redwoodjs.com/docs/how-to/using-a-third-party-api
And you can see my changes here
https://github.com/wispyco/conundrum-quest-rw-rebuild/pull/8/commits/41637813dd50be70e2e89372606c08e39618fa07
I have patient data in my databases represented in HTML that I want to print as an excel sheet using JSReport. But when I get the response from the jsreport server with the recipe it reads jibberish and I can't find a way to render it into an excel file.
Dummy example
const axios = require("axios");
const url = "http://localhost:5488/api/report/";
const data = {
"template": {
"shortid": "2_Kw0BRuOm",
"recipe": "html-to-xlsx",
"data": {
"people": [
{
"name": "Omar rafat",
"age": "20",
"job": "Software Engineer"
}
]
}
}
}
axios.post(url, {
"template": {
"shortid": "2_Kw0BRuOm",
"recipe": "html-to-xlsx",
"data": {
"people": [
{
"name": "Omar rafat",
"age": "20",
"job": "Software Engineer"
}
]
},
"options": { "reports": { "save": true } }
}
}).then(res => console.log(res.data)).catch(err => console.log(err));
Raw html-to-xlsx response
I might have missed up on the library's usage due to my misunderstanding of how the technology works but I really hope some of you might guide me on the correct implementation of it.
Thanks.
jsreport has nodejs client you can use
https://jsreport.net/learn/nodejs-client
You can check the following example on how to render a template and store the output to the file.
const client = require('jsreport-client')('http://localhost:5488')
const fs = require('fs').promises
async function render () {
const res = await client.render({
template: { shortid: '2_Kw0BRuOm' },
data: { someText: 'world!!' }
})
const responseBuffer = await res.body()
await fs.writeFile('out.xlsx', responseBuffer)
}
render().catch(console.error)
that's my API, i want to fetch it using axios
[
{
"groupType": "Interessegruppe",
"groups": [
{
"id": "c42b0250-375e-4458-8f68-0df8179f889c",
"name": "Teater",
"assignmentStrategy": 1
},
{
"id": "0fb94732-2bb1-483b-abbd-858327339ca0",
"name": "Fotball",
"assignmentStrategy": 1
},
{
"id": "6b109ab1-5a3e-46b0-b0cc-e2b48d6e2dc6",
"name": "Foto",
"assignmentStrategy": 1
}
]
},
]
I wrote that code
renderItem={({ item }) => <GroupCard title={item.groupType} subTitle={item.groups.name} />}
/>
and I fetched the groupType, but I can't fetch any of [ id or name]
async function loadData() {
const data = await axios.get(url)
return data[0].groups;
}
This function would return the groups array with id and name attributes.
what i am trying to do is fetching the data according to category id/slug. for e.g i have two categories(brown, black) as you can see below. how to fetch blog_set data according to category id/slug ?
i am probably new to ReactJs. it would be great if anyone could help me out what i am trying to do is. thank you so much in advance.
endpoint-url : http://localhost:8000/api/category
api-data:
[
{
"id": 1,
"title": "brown",
"slug": "brown",
"image": "http://localhost:8000/media/category/bg_1.jpg",
"description": "",
"created_on": "2020-05-08T15:21:02Z",
"status": true,
"blog_set": [
{
"id": 6,
"url": "http://localhost:8000/api/blog_detail/test3",
"title": "test3",
"slug": "test3",
"image": "http://localhost:8000/media/blog/author.jpg",
"description": "test3",
"created_on": "2020-05-13T13:36:45Z",
"status": true,
"category": [
1
]
}
]
},
{
"id": 2,
"title": "black",
"slug": "black",
"image": "http://localhost:8000/media/category/image_7.jpg",
"description": "",
"created_on": "2020-05-08T17:14:43Z",
"status": true,
"blog_set": [
{
"id": 10,
"url": "http://localhost:8000/api/blog_detail/test3",
"title": "Hamid",
"slug": "test3",
"image": "http://localhost:8000/media/blog/person_2_2beHkt1.jpg",
"description": "test",
"created_on": "2020-05-13T14:59:30.855849Z",
"status": true,
"category": [
2
]
}
]
}
]
./src/Category.js
export default class App extends Component{
state = {
bloglist: [],
};
componentDidMount() {
this.fetchData();
}
fetchData = async () => {
try {
const response = await fetch("http://localhost:8000/api/category");
const jsonResponse = await response.json();
this.setState({ bloglist: jsonResponse });
} catch (error) {
console.log(error);
}
};
render(){
{
const { bloglist } = this.state;
if (!bloglist) {
return (
<div>
<h1>loading...</h1>
</div>
);
}
return(
<div>
<h1>Category</h1>
{bloglist.map((bloglist) => (
<div>
<div class="col-md-12">
<div class="blog-entry animate d-md-flex">
<img src={bloglist.image} className="App-logo"/>
<h3 class="mb-2">{bloglist.title}</h3>
<h3 class="mb-2">{bloglist.blog_set.title}</h3>
</div>
</div>
</div>
))}
</div>
);
}
}
}
First check if the api supports fetching single category with id/slug. Then if you can call API with the id/slug from added to the fetch API call. If you want to show a separate page with the selected category you can enable a route with URL parameter with react-router-dom (https://reacttraining.com/react-router/web/example/url-params). And with this you will get the id/slug in the match prop which will be the this.props.history.match or with useParams() hooks. and then you can use it to call API with the selected id/slug.
Your UI URL will look like this. http://localhost:3000/category/:id and on browser it will look like this http://localhost:3000/category/black so when you call useParams() hook in your component it will be like {id} = useParams();
Now you can use this id to call the single selection API which might look like this <api_url>:<port>/category/black or <api_url>:<port>/category?slug=black
Pass query-params access deep properties
GET http://localhost:8000/api/category?slug=value
fetchData = async () => {
try {
const response = await fetch("http://localhost:8000/api/category?slug=value");
const jsonResponse = await response.json();
this.setState({ bloglist: jsonResponse });
} catch (error) {
console.log(error);
}
};
I'm trying to map 4 separate components into their respective rows using JSON data.
You can see the app here - https://stackblitz.com/edit/react-kt1zf8
Data.json
const data = {
"lanes":[
{
"_uid": "001",
"name": "Lane1",
"type": "Toll",
"cars":[
{
"component": "Bmw",
"name": "i8",
"number": "12345",
},
{
"component": "Lambo",
"name": "Aventador",
"number": "214512512",
},
]
},
{
"_uid": "002",
"name": "Lane2",
"type": "Easy Pay",
"cars":[
{
"component": "Fiat",
"name": "i8",
"number": "12345",
},
{
"component": "Dodge",
"name": "Aventador",
"number": "214512512",
},
]
},
]
}
export default data
The Rows are rendered in their own component using the "uid" key from JSON.
Mapping the row data (Lanes & Car Type) is rendering correctly. In the stack blitz, you can see the data in each row is unique.
However, when I try to map the nested data, only the results of the first lane is returning on both rows.
In the Components.jsx, I am using the unique id ("uid") key of the lanes in data.js to determine the lanes but can't figure out what I'm doing wrong. Why are only the first two results showing when they are using the same key?
CarContainer
const CarContainer = (props) => {
return (
<div className="car-container">
{props.data.cars.map(block => Components(block))}
</div>
);
};
export default CarContainer;
LaneInfo
const LaneInfo = () => {
const [laneData, setLaneData] = React.useState(null);
React.useEffect(() => {
setLaneData(data.lanes);
}, []);
return (
<>
{laneData &&
laneData.map((p) => (
<>
<div className="lane">
<div className="space" key={p.uid}>
<div>{p.name}</div>
<div>{p.type}</div>
</div>
</div>
<CarContainer data={p}/>
</>
))}
</>
);
};
export default LaneInfo;