Cannot retrieve Title from Strapi - javascript

I have collection type called posts and it has the following values:
Now to get the api I have a file in my lib folder which contains the following code:
export async function getPosts() {
var api_base_url = process.env.API_BASE_URL;
const response = await fetch(api_base_url + "/posts");
const posts = await response.json();
return posts;
}
export async function getPost(postId) {
var api_base_url = process.env.API_BASE_URL;
const response = await fetch(api_base_url + "/posts/" + postId);
const post = await response.json();
return post;
}
export async function getPostFromTitle(postTitle, lang) {
var api_base_url = process.env.API_BASE_URL;
const response = await fetch(api_base_url + "/posts");
const posts = await response.json();
var postObject = {};
posts.forEach(post => {
if (post['Title (' + lang.toUpperCase() + ')'] == postTitle) {
postObject = post;
}
});
return postObject;
}
Now to display this I have used the following code:
import { getPosts, getPostFromTitle } from '../lib/apiGet'
export async function getStaticProps() {
const allPosts = JSON.parse(JSON.stringify(await getPosts()));
const postsTitle = JSON.parse(JSON.stringify(await getPostFromTitle(postTitle, lang)));
//Parse and Stringify done since nextJs was having weird errors accepting the standard json from API
return {
props: {
allPosts,
postsTitle
}
}
}
export default function Home({ allPosts, postsTitle }) {
return (
<div>
<body>
<ul>
{allPosts.map(post => (
<h1><u>
{console.log(post.id)}
{post.id}
</u>
</h1>
))}
</ul>
<ul>
{postsTitle.map((postTitle, lang) => (
<h1><u>
{console.log(postTitle.Title)}
{postTitle.Title}
</u>
</h1>
))}
</ul>
</body>
</div>
);
}
I am able to get the id correctly, but when I go to print the Title I get this error.
So how do I retrieve my title correctly?

I believe the issue might be in your frontend function;
export async function getPostFromTitle(postTitle, lang) {
var api_base_url = process.env.API_BASE_URL;
const response = await fetch(api_base_url + "/posts");
const posts = await response.json();
var postObject = {};
posts.forEach(post => {
if (post['Title (' + lang.toUpperCase() + ')'] == postTitle) {
postObject = post;
}
});
return postObject;
}
It might not yield any post - i would debug the function. Is the "posts" const containing valid objects? does the return value seem correct or is it undefined?
Generally speaking, it would be much simpler for you to re-write the filter part of your function (everything beyond await response.json();) to use the js filter function.
Something like;
return posts.filter(post => post['...'].includes(postTitle));

Related

getStaticProps showing wrong/previous data in Reactjs

I am working on Rectjs,I am using nextjs, I created "[slug.js]" for dynamic routes,But its showing previous data instead of current data(fetching from database via axios),I checked in console.log,and in console showing old data not current,where i am wrong ?Here is my current code
const Post = function ({post}) {
useEffect(() => {
// showing old record/title instead of current
console.log(`Found Post title : ${post.title}`);
}, []);
};
export const getStaticProps = async ({ params }) => {
const { data } = await axios.get(
`https://diggdevelopment.com/blackstallion_new/api/getblogbyuserid/${params.slug}`
);
const post = data;
console.log('dat is' + post);
return {
props: {
post,
},
};
};
export const getStaticPaths = async () => {
const { data } = await axios.get(
'http://diggdevelopment.com/blackstallion_new/api/blogscopy'
);
const posts = data.slice(0, 10);
const paths = posts.map((post) => ({ params: { slug: post.id.toString() } }));
return {
paths,
fallback: true,
};
};

can't render fetched api data on my nextjs project

on this nextjs project i'm fetching data from an api and it's logging successfully. but i just can't seem to render the response (from the handleSubmit const) on my main jsx return. i try it as {cart.categoryTitle} and i got no error, but also no render on my app. am i doing something wrong? thanks!
import { useEffect, useState } from "react";
const Lista = () => {
const [categoryTitle, setCategoryTitle] = useState<any>();
const [cart, setCart] = useState([])
interface Data {
id: number;
title: string;
}
useEffect(() => {
handleCategoryData();
}, []);
async function handleCategoryData() {
const response = await fetch("/api/category");
const categoryTitle = await response.json();
setCategoryTitle(categoryTitle);
}
const handleSubmit = async (event: any) => {
event.preventDefault();
const categoryTitle = event.target[0].value;
const sub = event.target[1].value;
const name = [event.target[2].value];
const type = event.target[3].value == "Unidade" ? "unit" : "kg";
const price = event.target[4].value;
const counter = event.target[5].value;
//const img = event.target[6].value;
const res = await fetch("../api/list", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
products: [
{
categoryTitle,
sub,
name,
type,
price,
quantity,
},
],
}),
});
const response = await res.json();
console.log(response);
// return JSON.stringify(response);
setCart(response)
};
if (!categoryTitle) return <p>Loading</p>;
if (!sub) return <p>Loading</p>;
if (!productResponse) return <p>Loading</p>;
return (
<>
<section>
<div className="listsContainer">
<div className="cartContainer">
<div className="listText">
<p>Lista</p>
<p>{cart.categoryTitle}</p>
<p>0 categorias / 0 itens</p>
</div>
</div>
What does the response look like? Is it an object that has categoryTitle property? It may be the case that there’s no categoryTitle in the response object. Your cart state is being initialize as an array so maybe you are expecting the response to be an array as well?

Create dynamic routes by id from Next JS pages api

I have a page with a list of objects called stories that displays all my stories in an array. I also have a detail page with displays an individual story.
I want to click on a link on any given story on the list, then it will navigate me to the individual story. I want to use _id as my dynamic part of the URL, as shown in the GraphQL below.
My Graphql
export const listAllStories = () => {
const query = gql`
query StoryEntries($size: Int) {
storyEntries(_size: $size) {
data {
_id
_ts
name
premises{
data{
_id
content
}
}
createdAt
}
}
}
`
return graphQLClient
.request(query, { size: 999 })
.then(({ storyEntries: { data } }) => data)
}
IN MY PAGES API I HAVE
export default async function handler(req, res) {
const handlers = {
GET: async () => {
const storyEntries = await listAllStories()
res.json(storyEntries)
},
}
if (!handlers[req.method]) {
return res.status(405).end()
}
await handlers[req.method]()
}
ON THE STORY LIST PAGE I HAVE
const ENTRIES_PATH = '/api/entries/allStories'
const useEntriesFlow = ({ initialEntries }) => {
const { data: entries } = useSWR(ENTRIES_PATH, {
initialData: initialEntries,
})
const EntryItem = ({ entry }) => (
<>
{entries?.map((entry) => (
{entry.name}
<Link href="/story/[storyId]" as={`/story/${entry._id}`}>
<a>Go</a>
</Link>
))}
</>
)
export const getStaticProps = async () => ({
props: {
initialEntries: await listAllStories(),
},
revalidate: 1,
})
This is fine and works.
**AND THEN ON THE DETAIL PAGE FOR EACH INDIVIDUAL STORY [storyId].js I HAVE **
export default function Story({story}) {
const router = useRouter()
const storyId = router.query.storyId
return(
<>
<h5>hello {story._id}</h5>
</>
)
}
export const getStaticPaths = async () => {
const res = await fetch(`${server}/api/entries/allStories/`);
const { data } = await res.json();
const paths = data.map(story => {
return {
params: { id: story._id.toString() }
}
// trying to get the _id from each story
})
return {
paths,
fallback: false
}
}
export const getStaticProps = async (context) => {
const { storyId } = context.query; // Your dynamic page is [storyId].js
const server = "http://localhost:3000";
const res = await fetch(`${server}/api/entries/allStories/${storyId}`);
// trying to get the params._id from each story
console.log(res)
const { data } = await res.json();
return {
props: { story: data }
}
}
ERROR
TypeError: Cannot read properties of undefined (reading 'map')
QUESTION
All I want to do is click on any story link, then it takes me to the details page, via the _id. I have tried a few things but I'm doing something (or some things) wrong.
Any help will be greatly appreciated.
EDIT AFTER. ERROR I'M GETTING. I'm not able to map my results on getStaticPaths
export const getStaticProps = async (context) => {
const { storyId } = context.query; // Your dynamic page is [storyId].js
const server = "YOUR SERVER VARIABLE";
const res = await fetch(`${server}/api/entries/allStories/${storyId}`);
// trying to get the params._id from each story
const { data } = await res.json();
return {
props: { story: data }
}
}
uncomment
const router = useRouter()
const storyId = router.query.storyId
// some helpful links
// https://nextjs.org/docs/basic-features/data-fetching#the-paths-key-required
// https://stackoverflow.com/questions/65783199/error-getstaticpaths-is-required-for-dynamic-ssg-pages-and-is-missing-for-xxx
export const getStaticPaths = async () => {
const server = "http://localhost:3000";
const data = await fetch(`${server}/api/entries/allStories/`).then(res => res.json() )
const paths = data.map(({_id}) => ({
params: { storyId: _id },
}))
return {
paths,
fallback: false
}
}
export const getStaticProps = async (context) => {
const storyId = context.params.storyId; // Your dynamic page is [storyId].js
const server = "http://localhost:3000";
// const res = await fetch(`${server}/api/entries/allStories/${storyId}`);
// trying to get the params._id from each story
// single api call (here)
const res = await fetch(`${server}/api/entries/allStories/`);
// removing const { data } because the data will be returned when calling res.json()
const data = await res.json();
// instead of the calling the single api (just a fix not recommended to access [0] directly )
return {
props: { story: data.filter(story => story._id === storyId)[0] }
}
}

Not getting any data from API

import axios from 'axios';
const url = 'https://covid19.mathdro.id/api';
export const fetchData = async () => {
try {
const { data: { confirmed, recovered, deaths, lastUpdate} } = await axios.get(url);
return {confirmed, recovered, deaths, lastUpdate};
} catch (error) {
}
}
export const fetchDailyData = async()=> {
try{
const data = await axios.get('${url}/daily');
console.log("DATA",data);
const modifiedData = data.map((dailyData) => ({
confirmed: dailyData.confirmed.total,
deaths: dailyData.deaths.total,
date: dailyData.reportDate,
}));
return modifiedData;
} catch(error){
console.log("DATA NOT FOUND");
var r = []
return r
}
}
Here I'mt trying to get data from this API: https://covid19.mathdro.id/api/daily
But Whenever I'm trying to call fetchDailyData , I'm only getting "DATA NOT FOUND" on the console
You used ' instead of ` (near below escape button) to use string templates:
const data = await axios.get(`${url}/daily`);
Besides the ' wrong syntax, the data.map will also throw an error: map is not a function, because you are trying to map the response and not the response.data.
You should do something like that:
const data = await axios.get('${url}/daily');
To:
const response = await axios.get(`${url}/daily`);
And your map:
const modifiedData = data.map((dailyData) => ({
To:
const modifiedData = response.data.map((dailyData) => ({

How can I call function from div and render the json object returned?

I have the following react js code page:
import React, { useState } from "react";
import { Auth, API } from "aws-amplify";
function dailyFiles(props) {
const [apiError502, setApiError502] = useState(false);
// Pull out into a generic reusable function
const getData = async () => {
try {
let apiName = "Dev";
let path = "/test";
let myInit = {
headers: {
Authorization: `Bearer ${(await Auth.currentSession())
.getIdToken()
.getJwtToken()}`
}
};
var result = await API.get(apiName, path, myInit);
} catch (e) {
if (e.message === "Request failed with status code 502") {
toggleApiError502(true);
} else {
alert(JSON.stringify(e));
props.onLogout();
}
}
return result;
};
const toggleApiError502 = (show = false) => {
setApiError502(show);
};
var files = {
Files: [
{
Day: "Monday",
file: "10-02-2020"
},
{
Day: "Friday",
file: "14-02-2020"
}
]
};
return (
<div className="animated fadeIn">
<div>
{files.Files.map(block => block.Day + ": " + block.file + " ")}
</div>
</div>
);
}
export default dailyFiles;
When I call from my div the static Var files variable:
var files = {Files: [{Day: "Monday",file: "10-02-2020"},{Day: "Friday",file: "14-02-2020"}]};
<div>
{files.Files.map(block => block.Day + ": " + block.file + " ")}
</div>
I got the expected result, but how can I get the same result calling my function getData()?
const getData = async () => {
getData function call an API which return the same content result as var files has?
I've tried to call the function with this.getdata() within the div but not successful result.
Use useEffect to get the data after the component has mounted.
function dailyFiles(props) {
const [apiError502, setApiError502] = useState(false);
const [files, setFiles] = useState([]);
useEffect(() => {
// Pull out into a generic reusable function
const getData = async () => {
try {
let apiName = "Dev";
let path = "/test";
let myInit = {
headers: {
Authorization: `Bearer ${(await Auth.currentSession())
.getIdToken()
.getJwtToken()}`
}
};
var result = await API.get(apiName, path, myInit);
setFiles(result); // set your files here
} catch (e) {
if (e.message === "Request failed with status code 502") {
setApiError502(true);
} else {
alert(JSON.stringify(e));
props.onLogout();
}
}
return result;
};
// call getData
getData();
}, []);
return (
<div className="animated fadeIn">
<div>
{Array.isArray(files.Files) && files.Files.map(block => block.Day + ": " + block.file + " ")}
</div>
</div>
);
}
export default dailyFiles;
You're using a functional component so if you want to call the
getData function you should just use getData().
Anyway, since getData() is asynchronous you should make few
changes regarding how you use that inside the render function. For example, you can initially take a variable that has an empty array and once you get the data from the backend inside getData you can reassign that variable with the response data.
Actually you might want to call getData when your component loads for the first time so you can use Hooks for that.
There are several other ways it all comes down to your preference.

Categories