fetch data in react returns {} - reactjs

I have a react component , and I want to fill its state by fetching data from the url that I tested in browser and returns json data . but in my code I got nothing, here is my code :
fetch(`https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/posts.json`)
.then(response => response.json())
//.then(data => JSON.stringify(data))
.then(data => this.setState({
latitude: position.coords.latitude, // this ois ok
longitude: position.coords.longitude, /// this is ok
locations : data // here I get {}
}));
Problem is here in my render function
const { location } = this.state.locations;
alert("1" +JSON.stringify( this.state.locations));
alert("2" + JSON.stringify( location));
First alert is full with correct data but second alert returns undefined.

It looks like you're trying to destructure location from this reponse:
{
"posts": [
{
"_id": "5b3f761e21d434001487ad99",
"title": "Hello Word!",
"content": "The world is green!",
"__v": 0
},
{
"_id": "5b3f76b521d434001487ad9a",
"title": "Sed porttitor lectus nibh",
"content": "Sed porttitor lectus nibh. Praesent sapien massa, convallis a pellentesque nec, egestas non nisi. Pellentesque in ipsum id orci porta dapibus. Proin eget tortor risus. Pellentesque in ipsum id orci porta dapibus. Curabitur aliquet quam id dui posuere blandit. Quisque velit nisi, pretium ut lacinia in, elementum id enim. Pellentesque in ipsum id orci porta dapibus. Vestibulum ac diam sit amet quam vehicula elementum sed sit amet dui. Vestibulum ac diam sit amet quam vehicula elementum sed sit amet dui.",
"__v": 0
}
]
}
As you can see, it doesn't have a location property so the result of your destructure will be undefined. Are you hitting the right endpoint?

Related

React store data in a variable from API

I am trying to store some of my data in a const variable. Like I am getting FAQ section data from an API call. Like this one, I have my data in restaurant.faq and there can be multiple data so I map through it and it is working perfectly. Suppose Now I have two questions and two answers and I am getting it perfectly.
{restaurant.faq?.map((f) => (
<ListGroup.Item key={f.id}>
Question - <strong>{f.question}</strong>
<br />
Answer - <strong>{f.answer}</strong>
</ListGroup.Item>
))}
But I want to pass the same question and answer from this restaurant.faq in a const variable
Like this in rows [{question, answer}] section. How Can I do this?
const data = {
title: "FAQ",
rows: [
{
question: "Lorem ipsum dolor sit amet,",
answer: `Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sed tempor sem. Aenean vel turpis feugiat,
ultricies metus at, consequat velit. Curabitur est nibh, varius in tellus nec, mattis pulvinar metus.
In maximus cursus lorem, nec laoreet velit eleifend vel. Ut aliquet mauris tortor, sed egestas libero interdum vitae.
Fusce sed commodo purus, at tempus turpis.`,
},
{
question: "Nunc maximus, magna at ultricies elementum",
answer:
"Nunc maximus, magna at ultricies elementum, risus turpis vulputate quam, vitae convallis ex tortor sed dolor.",
},
],
};
Update how to do the same with this one?
{restaurant.menu?.map((men) => (
<ListGroup.Item key={men.id}>
<Image src={men.image} alt={men.name} style={{height:'250px', width:'1800px'}} fluid />
</ListGroup.Item>
))}
const images = [
{
original: 'https://picsum.photos/id/1018/1000/600/',
},
{
original: 'https://picsum.photos/id/1015/1000/600/',
},
{
original: 'https://picsum.photos/id/1019/1000/600/',
},
];
You can do like this
const data = {
title: "FAQ",
rows: restaurant.faq?.map(({ question, answer}) => (
{ question,
answer
})
)

Next.JS - Gist's embedded in markdown rendered via dangerouslySetInnerHTML only show after full page load, not React route load

I have a series of blog posts stored in MD files, some of these contain multiple Gist embeds in the form of script tags.
The MD contents are rendered to the page via dangerouslySetInnerHTML, and all is fine when the page is navigated to directly. However when the app's routing is used and a full page refresh doesn't happen the script tag is included in the markup, but not executed.
The following example is using the default Next.JS blog example here: https://github.com/vercel/next-learn-starter/tree/master/basics-final.
Markdown:
---
title: "Example of GIST embedding"
date: "2020-02-20"
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut id arcu at arcu pretium porta. Nam feugiat est ut lectus imperdiet venenatis. Ut tempus vitae lectus id vestibulum. Sed tristique est metus. Ut pretium malesuada risus. Maecenas eget diam tristique, sagittis velit ac, efficitur nisi. Quisque lectus lorem, vehicula at mi vitae, dapibus volutpat augue. Sed dignissim pharetra ligula a efficitur. In ultrices imperdiet libero. Quisque ornare erat eu elit ullamcorper faucibus. Maecenas mattis sem a mauris posuere iaculis.
<script src="https://gist.github.com/robearlam/aec15c65aaffbd5ec00a826c5cbe57ad.js"></script>
Etiam sed interdum ligula, nec tincidunt justo. Aliquam erat volutpat. Fusce in scelerisque nisl. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin venenatis lectus at ligula mollis dapibus. Praesent condimentum metus fringilla, commodo enim non, fringilla dui. Vivamus nec ligula lacinia ante semper rhoncus eu sed nisi. In ac dolor vel lorem tincidunt lacinia. Praesent quis mattis mi, at finibus velit. Etiam auctor, magna fermentum tincidunt interdum, nulla augue porttitor enim, ac lobortis felis eros id dui. Suspendisse dignissim, dui sit amet pulvinar iaculis, nisi tellus rhoncus dolor, eu gravida risus massa accumsan magna.
Page
import Layout from '../../components/layout'
import { getAllPostIds, getPostData } from '../../lib/posts'
import Head from 'next/head'
import Date from '../../components/date'
import utilStyles from '../../styles/utils.module.css'
export default function Post({ postData }) {
return (
<Layout>
<Head>
<title>{postData.title}</title>
</Head>
<article>
<h1 className={utilStyles.headingXl}>{postData.title}</h1>
<div className={utilStyles.lightText}>
<Date dateString={postData.date} />
</div>
<div dangerouslySetInnerHTML={{ __html: postData.contentHtml }} />
</article>
</Layout>
)
}
export async function getStaticPaths() {
const paths = getAllPostIds()
return {
paths,
fallback: false
}
}
export async function getStaticProps({ params }) {
const postData = await getPostData(params.id)
return {
props: {
postData
}
}
}
Lib function
export async function getPostData(id) {
const fullPath = path.join(postsDirectory, `${id}.md`)
const fileContents = fs.readFileSync(fullPath, 'utf8')
// Use gray-matter to parse the post metadata section
const matterResult = matter(fileContents)
// Use remark to convert markdown into HTML string
const processedContent = await remark()
.use(html)
.process(matterResult.content)
const contentHtml = processedContent.toString()
// Combine the data with the id and contentHtml
return {
id,
contentHtml,
...matterResult.data
}
I also have a repo showing the issue here: https://github.com/robearlam/gist-embedding-issue
Cheers!
I ran into this same problem, I found this post to be very helpful.
Basically, you create a custom code block that formats your code tags inline.
It has you use <ReactMarkdown> component to render your markdown (instead of remark) and then you use the react-syntax-highlighter library in your custom code block component.
When rendering your markdown use:
import CodeBlock from "../../components/codeblock"
<ReactMarkdown components={CodeBlock}>{your markdown data here}</ReactMarkdown>
Importing your custom codeblock component for the markdown processor.
Tom's custom code block example below:
// components/codeblock.js
import React from "react"
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"
import {dracula} from 'react-syntax-highlighter/dist/cjs/styles/prism';
const CodeBlock = {
code({node, inline, className, children, ...props}) {
const match = /language-(\w+)/.exec(className || '')
return !inline && match ? (
<SyntaxHighlighter
style={dracula}
language={match[1]}
PreTag="div" {...props}>
{String(children).replace(/\n$/, '')}
</SyntaxHighlighter>
) : (
<code className={className} {...props}>
{children}
</code>
)
}
}
export default CodeBlock

Api-platform accessing embedded relations in hydra:member

I'm using Api-Platform and React as client.
I have a Forum entity which contains other objects : an author (User entity) and a category (Category entity).
I embedded these entities with #Groups annotations to retrieve them more easily.
For instance, when I fetch /api/forums/ on Postman I get this result :
{
"#context": "/api/contexts/Forum",
"#id": "/api/forums",
"#type": "hydra:Collection",
"hydra:member": [
{
"#id": "/api/forums/79",
"#type": "Forum",
"id": 79,
"subject": "Sujet numéro 0",
"message": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"category": {
"#id": "/api/categories/183",
"#type": "Category",
"title": "Category 2"
},
It seems good : we can see my category object is linked to Forum in hydra:member array, and a "title" field.
But I noticed that the result I really get is different in my react app for all my nested objects.
I only get the IRIs..
For instance with the same request :
...
fetch('forums')
.then(response =>
response
.json()
.then(retrieved => ({ retrieved, hubURL: extractHubURL(response) }))
)
.then(({ retrieved, hubURL }) => {
retrieved = normalize(retrieved);
...
I get this result :
{
"#context": "/api/contexts/Forum",
"#id": "/api/forums",
"#type": "hydra:Collection",
"hydra:member": [
{
"#id": "/api/forums/79",
"#type": "Forum",
"id": 79,
"subject": "Sujet numéro 0",
"message": "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
"category": "/api/categories/183",
Every other fields have disapeared on "category", and I don't get why.
Could anyone help me with that ?
Thanks in advance
I found the solution (how silly of me), so I share you the tip :
In src/utils/dataAccess file, there is a normalize function :
export function normalize(data) {
if (has(data, 'hydra:member')) {
// Normalize items in collections
data['hydra:member'] = data['hydra:member'].map(item => normalize(item));
return data;
}
// Flatten nested documents
return mapValues(data, value =>
Array.isArray(value)
? value.map(v => get(v, '#id', v))
: get(value, '#id', value)
);
}
It appears that this function is called after each fetch :
return fetch(id)
.then(response =>
response
.json()
.then(retrieved => ({ retrieved, hubURL: extractHubURL(response) }))
)
.then(({ retrieved, hubURL }) => {
//retrieved = normalize(retrieved);
dispatch(loading(false));
dispatch(success(retrieved));
....
As you can see, I just commented the normalize line (useless in my case). Do that wherever it is needed, and everything should work again !

How to call single api in multiple react component with mixed up server side code?

Below is my nested object json, where i want access the properties in different react component
{
"Created":"2017-02-09",
"SenderOrReceiver":"Not developed yet",
"PageResponsible":"Yogesh Shinde",
"LastUpdated":"2017-02-09",
"ExternalLinks":[
{
"Id":null,
"Title":"Yahoo",
"Url":"http://yahoo.com"
},
{
"Id":null,
"Title":"Facebook",
"Url":"http://facebook.com"
}
],
"InternalLinks":[
{
"Id":null,
"Title":"Google",
"Url":"~/link/23199285feef4501987b5fa452e49b94.aspx"
}
],
"Appendices":[
{
"Id":null,
"Title":"React",
"Url":"~/link/23199285feef4501987b5fa452e49b94.aspx"
}
],
"ContactDetails":{
"Email":"user#gmail.com",
"Information":"Aliquam mollis, quam nec suscipit placerat, nibh est efficitur urna, in ornare mauris eros eu tortor. Nulla fermentum hendrerit mi, nec luctus nunc auctor at. Nullam sagittis posuere libero, eget imperdiet neque. Etiam ac lacus diam. Mauris sapien turpis, lobortis non eros in, porttitor dapibus ipsum.",
"Name":"user1",
"Telephone":"11234"
},
"Subject":[
"Lorem"
],
"HeadingLinks":[
{
"Id":"headinglink1",
"Title":"Heading1",
"Url":"/sv/news-page/#headinglink1"
}
]
}
Below is my server side index.cshtml (Layout)
#model intrav2.infrastructure.ViewModels.Pages.NewsPageViewModel
<div class="l-content_primary" role="main">
<div id="breadcrumb"></div>
<h2>#Html.PropertyFor(x => x.CurrentPage.Heading)</h2>
<div id="newcreatedinfo"></div>
<div>#Html.PropertyFor(x => x.CurrentPage.Media)</div>
<p class="preamble">#Html.PropertyFor(x => x.CurrentPage.Preamble)</p>
<div id="newsHeadingLinks"></div>
<p>#Html.PropertyFor(x => x.CurrentPage.MainBody)</p>
#Html.PropertyFor(x => x.CurrentPage.ExtraInformation)
<div id="newspagecontent"></div>
</div>
<aside class="l-blocks_secondary" role="complementary" id="newsSiderBar"></aside>
Now i want,
Created/SenderOrReceiver property in newcreatedinfo
External and Internal links in newspagecontent
Appendices/Contact in side content on page

append a json object to an array within my postgres table

I have a postgres table which stores some JSON using Groovy sql, I want to append an object to my 'players' array to add a new player to my database. At the moment I am trying this.I try to target my 'players' array and append my new json which comes from the server. This gives me an error
.PSQLException: ERROR: function array_append(jsonb, jsonb) does not
exist
I think I may be getting this error has the first param needs to be an array not jsonb, is there a way to target the array in my db so it comes back as an array? Or is there a better way to append this object to my array?
sql.executeUpdate("""
UPDATE site_content
SET content = array_append(content->'playersContainer'->'players', '${json}'::jsonb);
where id = :id
""", id: player.teamId)
}
Here is my JSON
"playersContainer": {
"players": [
{
"id": "1",
"name": "Nick Pocock",
"teamName": "Shire Soldiers",
"bio" : "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla imperdiet lorem tellus, in bibendum sem dignissim sed. Etiam eu elit sit amet lacus accumsan blandit sed ut dolor. Mauris vel dui non nisi vestibulum commodo vel id magna. Donec egestas magna in tincidunt mollis. Fusce mauris arcu, rhoncus ut lacus sed, fermentum ultrices elit. In sollicitudin at ex dapibus vestibulum. Pellentesque congue, est id lobortis viverra, mauris lectus pharetra orci, ut suscipit nisl purus vehicula est. Aliquam suscipit non velit vel feugiat. Quisque nec dictum augue.",
"ratings": [
1,
5,
6,
9
],
"assists": 17,
"manOfTheMatches": 20,
"cleanSheets": 1,
"data": [
3,
2,
3,
5,
6
],
"totalGoals": 19
}
}
My column is called content which holds the JSONb
For 9.5:
UPDATE site_content
SET content = jsonb_set(content, '{playersContainer,players}'::text[], content->'playersContainer'->'players' || '${json}'::jsonb);
where id = :id

Resources