How to render HTML stored inside an object? - html

I am using nextjs. I need to render custom landing pages according to their specific url. I am able to render all the details from the database of that particular URL except for the object which contains the details for the page. The pages has been built with the help of grapesjs.
Following is the data in db:
Following is code for rendering the list of the pages:
index.js
import Link from "next/link"
export const getStaticProps = async () => {
const res = await fetch("http://localhost:5000/api/webpage/");
const data = await res.json();
return {
props: {
data,
}
};
};
const blog = ({ data }) => {
return (
<div>
{data?.map((currentElement) => {
return (
<div key={currentElement.id} className="ssr-styles">
<h3>
{/* {currentElement._id} */}
<Link href={`/blog/${currentElement.url}`}>
{currentElement.name}
</Link>
</h3>
</div>
);
})}
</div>
);
};
export default blog;
Following is the code where the page is actually rendering:
[pageno].js=>
export const getStaticPaths = async () => {
const res = await fetch("http://localhost:5000/api/webpage/");
const data = await res.json();
const paths = data.map((currentElement) => {
return {
params: { pageno: currentElement.url.toString() }
};
});
return {
paths,
fallback: false
};
};
export const getStaticProps = async (context) => {
const url = context.params.pageno;
const res = await fetch(`http://localhost:5000/api/webpage/url/${url}`);
const data = await res.json();
return {
props: {
data
}
};
};
export const Details = ({ data }) => {
return (
<>
<div key={data.url} className="ssr-styles">
{data._id}
<h3>{data.name}</h3>
</div>
</>
);
};
export default Details;
how do I render the html inside the object content so as to get a proper webpage?

you can try using html-react-parser library. it converts an HTML string to React elements.

Related

NextJS get custom JSON depending on page

I know you can do the following
export async function getStaticProps({ params }) {
console.log(params)
const res = await fetch(`https://example.com/api-access/news/2021_autumn_home_style_tips`)
const data = await res.json()
if (!data) {
return {
notFound: true,
}
}
return {
props: { data }, // will be passed to the page component as props
}
}
however what if the last part depending on the news item a user presses needs to change.
https://example.com/api-access/news/2021_autumn_home_style_tips
https://example.com/api-access/news/2020_autumn_home_style_tips
https://example.com/api-access/news/2021_car
https://example.com/api-access/news/top_songs
How can I make a [slug].js page that allows me to run that slug url for example
https://myexample.com/news/top_songs
would fetch data from https://example.com/api-access/news/top_songs
I have tried
export const getStaticPaths: GetStaticPaths<{ slug: string }> = async () => {
console.log(params)
const res = await fetch('https://example.com/api-access/news/{slug}')
const data = await res.json()
if (!data) {
return {
notFound: true,
}
}
return {
props: { data }, // will be passed to the page component as props
}
}
But get this error

Change number of servings on click (React Hooks - API)

I'm working on a recipe site using API from a third party and want to change the number of servings (which is output from the API data) when clicking the + & - button. I tried assigning the output serving amount <Servings>{recipe.servings}</Servings> in a variable and useState to update it but it kept showing errors. I would appreciate any help (preferably using react Hooks). Thanks :)
Here is my code:
const id = 716429;
const apiURL = `https://api.spoonacular.com/recipes/${id}/information`;
const apiKey = "34ac49879bd04719b7a984caaa4006b4";
const imgURL = `https://spoonacular.com/cdn/ingredients_100x100/`;
const {
data: recipe,
error,
isLoading,
} = useFetch(apiURL + "?apiKey=" + apiKey);
const [isChecked, setIsChecked] = useState(true);
const handleChange = () => {
setIsChecked(!isChecked);
};
return (
<Section>
<h2>Ingredients</h2>
<ServingsandUnits>
{recipe && (
<ServingsIncrementer>
<p>Servings: </p>
<Minus />
<Servings>{recipe.servings}</Servings>
<Plus />
</ServingsIncrementer>
)}
<ButtonGroup>
<input
type="checkbox"
id="metric"
name="unit"
checked={isChecked}
onChange={handleChange}
/>
<label htmlFor="male">Metric</label>
</ButtonGroup>
</ServingsandUnits>
</Section>
};
My custom hook is called useFetch:
const useFetch = (url) => {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const abortCont = new AbortController();
fetch(url, { signal: abortCont.signal })
.then((res) => {
if (!res.ok) {
// error coming back from server
throw Error("Could not fetch the data for that resource");
}
return res.json();
})
.then((data) => {
setIsLoading(false);
setData(data);
setError(null);
})
.catch((err) => {
if (err.name === "AbortError") {
console.log("Fetch aborted");
} else {
// auto catches network / connection error
setIsLoading(false);
setError(err.message);
}
});
return () => {
abortCont.abort();
};
}, [url]);
return { data, isLoading, error };
};
export default useFetch;

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([]);

Component nesting in react with ES6 syntax

When working on a name card generator app, trying to extract information from address object (https://jsonplaceholder.typicode.com/users). Was told the best way to present the text is to put them in separate components, and . Now I am having troubles piecing the two components together. The code is down below.
(Complete set of new code will be appreciated!)
import React, { useState, useEffect } from 'react';
const Namecard = ({ name, email, address }) => {
return (
<div>
<p>{name}</p>
<p>{email}</p>
</div>
);
};
const Address = ({ street }) => {
return <h1>{street}</h1>;
};
function App() {
const [identis, setIdenti] = useState([]);
useEffect(() => {
getIdenti();
}, []);
const getIdenti = async () => {
const acquired = await fetch(`https://jsonplaceholder.typicode.com/users`);
const data = await acquired.json();
setIdenti(data);
};
return (
<div>
{identis.map(identi => (
<Namecard name={identi.name} email={identi.email}>
<Address street={identi.address.city} />
</Namecard>
))}
</div>
);
}
export default App;
So with the current code, the output only includes name and email. Nothing is shown from the address object.
Namecard needs to explicitly render its children, otherwise they are not rendered:
const Namecard = ({name,email,children}) => {
return (
<div>
<p>{name}</p>
<p>{email}</p>
{children}
</div>
)
}
You use Address component as a children of Namecard component, so you should tell Namecard component that use this children component and render in his body.
For example you could rewrite Namecard component like that:
const Namecard = ({name, email, address, children}) => {
return (
<div>
<p>{name}</p>
<p>{email}</p>
{children}
</div>
)
};
and as a children our component render <Address street={identi.address.city}/>
Or you could rewrite like that: render Address component inside Namecard:
const Namecard = ({name, email, address}) => {
return (
<div>
<p>{name}</p>
<p>{email}</p>
<Address street={address.city}/>
</div>
)
};
const Address = ({street}) => <h1>{street}</h1>;
function App() {
const [identis, setIdenti] = useState([]);
useEffect(() => {
getIdenti();
}, []
);
const getIdenti = async () => {
const acquired = await fetch(`https://jsonplaceholder.typicode.com/users`);
const data = await acquired.json();
setIdenti(data);
}
return (
<div>
{identis.map(identi => (
<Namecard
name={identi.name}
email={identi.email}
address={identi.address}
/>
))}
</div>
)
}

Using fetch to render json data in react app

I am trying to render some JSON about a person's location from an api in my react app.
I am using isomorphic-fetch to access the data from the API I can add the base test in and it correctly logs the data using below.
require('isomorphic-fetch');
require('es6-promise').polyfill();
var url = 'http://localhost:3000/api/data'
fetch(url)
.then(function(response) {
if (response.status >= 400) {
throw new Error("Bad response from server");
}
return response.json();
})
.then(function(data) {
console.log(data);
});
What i'm trying to work out is how I can take this response and render it in my component which currently looks like this (in this example code below data is coming from local json file so i need to merge them together).
I've attempted to set up componentDidMount but could get my head around the syntax so it kept breaking, I also checked out redux actions but that exploded my brain.
const personLoc = Object.keys(data.person.loc).map((content, idx) => {
const items = data.person.loc[content].map((item, i) => (
<p key={i}>{item.text}</p>
))
return <div key={idx}>{items}</div>
})
export default function PersonLocation() {
return (
<div className="bio__location">
{personLoc}
</div>
)
}
componentDidMount should setState:
componentDidMount() {
var that = this;
var url = 'http://localhost:3000/api/data'
fetch(url)
.then(function(response) {
if (response.status >= 400) {
throw new Error("Bad response from server");
}
return response.json();
})
.then(function(data) {
that.setState({ person: data.person });
});
}
The render component should map the state:
const personLoc = Object.keys(this.state.person.loc).map((content, idx) => {
const items = this.state.person.loc[content].map((item, i) => (
<p key={i}>{item.text}</p>
))
return <div key={idx}>{items}</div>
})