React JS fetching data (error: Cannot read properties of undefined) - javascript

i am just trying to learn JavaScript. I have to create a web application for school. Now i am trying to fetch data from a self written api. The backend is written with express, the frontend with JavaScript. I have got a overview page, where all products are shown. After clicking on the detail button, the user should be able to view the details of the selected product. For this i use this code.
import React, { useState, useEffect } from "react";
import "./Articles.css";
function ArticleDetail({ match }) {
useEffect(() => {
fetchArticle();
}, []);
const [article, setArticle] = useState([]);
async function fetchArticle() {
try {
const response = await fetch(
`http://localhost:8000/api/articles/${match.params.id}`
);
const article = await response.json();
//console.log(data.results);
console.log(article);
setArticle(article);
return article;
} catch (error) {
console.error(error);
}
}
return (
<div>
<p>TEST</p>
<p>{article.articles.pk_article_nr}</p>
<p>TEST</p>
</div>
);
}
export default ArticleDetail;
If i run this code and don't refresh the page by myself, the correct value (pk_article_nr) is shown. If i refresh the browser manually there is this error
TypeError: Cannot read properties of undefined (reading 'pk_article_nr')
This data are shown in the console:
{articles: {…}}
articles:
article_description: "lorem ipsum"
article_expiretimestamp: "2022-01-15 18:52:27"
article_picture: null
article_timestamp: "2022-01-15 18:37:27"
article_title: "Test 4"
bid_amount: 80
fk_article_nr: 4
fk_user_userid: null
pk_article_nr: 4
pk_bid_id: 8`
Could you please help me? I haven't found anything that helps me. Maybe i just searched for the wrong thing.
Thank you,
Max

You should change
<p>{article.articles.pk_article_nr}</p>
to
<p>{article?.articles?.pk_article_nr}</p>
Reason for this to happen:
React wants to access the property before mounting, while the property has not yet received any content

Related

NextJS page does not re-hydrate when refreshed

I am building a NextJS blogging site which uses #expo/next-adapter . This site has two pages. One is the user page and the other one is post page. The user page has getServerSideProps implemented to fetch data from Firebase. There is next/link's <Link /> implemented on the post page which points to /user/[uid].
Now the problem is if I navigate to user from post using the <Link /> Everything works ok but if I refresh the page the page becomes unresponsive and all the styling related client side JS does not run.
PS : SSR is not implemented on the post page. Please forgive me if this is a rookie mistake because I am one.
PS #2 : This project is hosted on Firebase and uses a cloud function to handle SSR. The above problem does not show up if I run the production build locally using next build && next start
Thank you in advance...
Edit #1 :
This error shows up on the browser console when I either try to manually go to /user/[uid] or refresh the page after navigating back from post
main-590e886005382c6f8e8a.js:1 Uncaught TypeError: Cannot read property 'map' of undefined
at DqTX.t.default (main-590e886005382c6f8e8a.js:1)
at Object.IKlv (main-590e886005382c6f8e8a.js:1)
at l (webpack-288ceb4b356766e18474.js:1)
at Object.BMP1 (main-590e886005382c6f8e8a.js:1)
at l (webpack-288ceb4b356766e18474.js:1)
at t (webpack-288ceb4b356766e18474.js:1)
at Array.r [as push] (webpack-288ceb4b356766e18474.js:1)
at 0c947092cfe8a35964e0670062fe3410218106ea.62154c5756c292e8972d.js:1
Edit #2: Code for the function [user].js
export async function getServerSideProps(context) {
if(admin.apps.length == 0){
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
storageBucket: '*************.appspot.com',
});
}
try {
const fireStore = admin.firestore();
const userDataRef = await fireStore.collection('users').where('uid', '==', `${context.query.user}`).get();
const postDataRef = await fireStore.collection('posts').where('uid', '==', `${context.query.user}`).get();
let userData;
let postData = [];
if(!userDataRef.empty){
if(userDataRef.docs[0].exists){
userData = userDataRef.docs[0].data()
}
if(!postDataRef.empty){
for(let post of postDataRef.docs){
const thumbImage = await admin.storage().bucket().file(`postData/${post.id}/${post.data().thumb}`).publicUrl();
deckData.push(JSON.parse(JSON.stringify({...post.data(), id: post.id, thumb: thumbImage})));
}
}
}
return {
props: {user: JSON.parse(JSON.stringify(userData)), posts: [...postData]}, // will be passed to the page component as props
}
} catch(e) {
return {
props: {user: 'error', posts: []},
}
}
}

Why it sends multiple request, when I call it only once?

My project were working fine. I just found out in console network that one of my GET request is sending twice, even I just send it once. See network console
If I comment the the whole code of created function, all GET request would no longer load/exist in the console network. (see code below)
I want to know what causes this, and how should I fix this?
Here is the Component.vue
<script>
export default {
created: async function() {
await this.$store.dispatch('file/all');
},
};
</script>
And the vuex module post.js's action:
const actions = {
all({commit}, data) {
return axios.get(`files`)
.then(response => {
commit('setData', response);
});
},
}
After many hours of searching, I found out that the key that is assigned to the Component caused the problem.
When the key is modified the GET request will send again. This the reason why it sends twice. Special thanks to #Anatoly for giving me the hint.
Below is the usage codes:
<template>
<Component :key="componentKey" #edit="dataIsChanged"/>
</template>
<script>
export default {
components: { Component },
data: () => ({
componentKey: 0,
}),
methods: {
dataIsChanged: function() {
this.componentKey = Math.random();
}
}
};
</script>

Uncaught (in promise) TypeError: Cannot read property 'length' of undefined ERRORr

I am experiencing this problem when trying to apply a condition to display articles from my database
This is my Article.js component which is where the error indicates
import React, { Component } from 'react';
import axios from 'axios';
class Articles extends Component {
state = {
articles: [],
status: null
}
componentWillMount() {
this.getArticles();
}
getArticles = () => {
axios.get("https://arthuro-gomez-react.netlify.app/api/articles")
.then(res => {
this.setState({
articles: res.data.articles,
status: 'success'
});
});
}
render() {
if (this.state.articles.length >= 1) {
var listArticles = this.state.articles.map((article) => {
return (
<article className="article-item" id="article-template">
<div className="image-wrap">
<img
src="https://unhabitatmejor.leroymerlin.es/sites/default/files/styles/header_category/public/2018-
10/4%20paisaje%20macedonia.jpg?itok=AELknmF8" alt="Paisaje" />
</div>
<h2>{article.title}</h2>
<span className="date">
{article.date}
</span>
Leer más
<div className="clearfix"></div>
</article>
);
});
return (
<div id="articles">
{listArticles}
</div>
);
} else if (this.state.articles.length === 0 && this.state.status === 'success') {
return (
<div id="articles">
<h2 className="subheader">No hay articulos para mostrar</h2>
<p>Todavia no hay contenido en esta sección</p>
</div>
);
} else {
return (
<div id="articles">
<h2 className="subheader">Cargando</h2>
<img
src="https://pa1.narvii.com/6707/510b0daee67fbc091f14b9d8ef40aeb6c0d4dc7d_hq.gif"/>
</div>
);
}
}
}
export default Articles;
Research other OS posts but don't come up with a solution
It should be noted that when I open the page, it does as normal load and then leaves everything blank
I just checked the network console to see and everything marks be directing where it is, if you could see my github repository and see something weird I would appreciate it GitHub Repository
And my app web App web
Your API is not working, check this picture from insomia
Check your api. By this your length is empty.
Or try this way
Axios.get('http://localhost:yourport/api/someroute')
.then(res =>{
const data = res.data;//to save your data response
console.log("----SETTING DATA-----")
console.log(data)//to see your data response
this.setState({articles}) //to set your data response
console.log("++++++ALL DATA WAS SETTING++++++")
}).catch(err=>{
console.log(err)
})
These are generic errors that occur due to the unhandled error that occurred in your code, it mostly because of mismatching between what expected and what received.
In such cases, you need to try debugging your code to identify what gets failed or different from what expected. This is something considered as drawback of using Javascript as it's not type proof and you encounter such errors a lot.
But browsers help in debugging, so logs you pasted above is the stack trace of chrome and you can identify where it's failing. It's not guaranteed though as sometimes you probably worked with minified scripts but it's useful a lot.
Top log which states error article.js click on that it will point you the line of the page where you getting this error, add logs there and you will get an answer.
As just by seeing you probably trying to get length of something which is not available.
Try add a log for res and see what you received
axios.get("https://arthuro-gomez-react.netlify.app/api/articles")
.then(res => {
console.log(res)
this.setState({
articles: res.data.articles,
status: 'success'
});
});
}
I already knew what was happening, something very embarrassing haha, I did not take the routes, because my backend was not in line with netlify, only my frontend, so I proceeded to upload my backend project in heroku and only connected my Global variable for the routes, pointing to the link that indicated heroku :) and ready, solved, thank you all for your time.

Stripe not being called

I am trying to use Vue.js for my front end to call Stripe and create a token which then is sent to my backend. I have tested everything using plain HTML/JS and it all works fine, my issue comes in trying to use Vue.js I think my issue might be in how I am binding the stripe public key. Below is my code, and I have zero output to speak of, I get just redriected to the same page but wth ? at the end of the URL. Nothing else, console shows nothing and no error message or anything send to my back end.
template code
There is more but not related
<div class="col-md-8">
<card class='stripe-card col-md-8'
:class='{ complete }'
:stripe='stripeKey'
:options='stripeOptions'
#change='complete = $event.complete'
/>
<button class='pay-with-stripe' #click='pay' :disabled='!complete'>Submit Payment Details</button>
<br>
</div>
script section with relavent added
import { Card, createToken } from 'vue-stripe-elements-plus'
import axios from 'axios';
export default {
components: { Card },
data() {
return {
errorMessage: null,
successMessage: null,
complete: false,
stripeKey: process.env.VUE_APP_STRIPE_PUB_KEY,
stripeOptions: {
// see https://stripe.com/docs/stripe.js#element-options for details
hidePostalCode: true
},
current: {
stripe: {
plan: null,
last4: null
}
},
}
},
methods: {
pay () {
createToken().then(result => {
axios.post('/billing/updateCard', {
token: result.token,
})
.then(res => {
if(res.data.success == true) {
this.successMessage = res.data.message
console.log(res.data.message)
}
if(res.data.success == false) {
this.errorMessage = res.data.message // Display error message from server if an error exists
}
})
.catch((err) => {
if(err) console.log(err)
if(err) this.$router.push('/company/settings?success=false')
})
});
}
}
}
</script>
I have checked that the API key is actually in the data value by doing <p>{{ stripeKey }}</p> and seeing the value show up. So yes the key is there and the key is valid (tested copy/paste into my HTML/JS test)
created(){
this.key=process.env.VUE_APP_STRIPE_KEY;
}
try this, i used this piece of code in my project and it worked... the issue maybe is that your key is not yet initialized when card us rendered idk. maybe key isnt issue at all. try this and let me know if works and we will debug it together.

Django Rest Framework + ReactJS: Whats wrong with my API?

I'm trying to fetch data from a django rest-framework API, using `ReactJS' but I keep facing the same error:
SyntaxError: "JSON.parse: unexpected character at line 1 column 1 of the JSON data"
I think the actual problem is is in my API, since I have already tried 3 different approaches to get the data into React. Maybe somebody knows what I can do to my API to make it work? Im using the djangorestframework library. The API looks as following:
{
"questions":"http://127.0.0.1:8000/api/questions/?format=json",
"choices":"http://127.0.0.1:8000/api/choices/?format=json"
}
And the React Component I'm using to retreive the data is the following:
import React, { Component } from 'react';
class ApiFetch extends Component {
state = {
data: []
};
async componentDidMount() {
try {
const res = await fetch('127.0.0.1:8000/api/?format=json');
const data = await res.json();
this.setState({
data
});
console.log(this.state.data)
} catch (e) {
console.log(e); //SyntaxError: "JSON.parse: unexpected character at line 1 column 1 of the JSON data"
}
}
render() {
return (
<div>
{(this.state.data)}
</div>
);
}
}
export default ApiFetch;
The Header of the API looks like that:
allow →GET, HEAD, OPTIONS
content-length →123
content-type →application/json
date →Fri, 17 Aug 2018 11:01:36 GMT
server →WSGIServer/0.2 CPython/3.6.3
vary →Accept, Cookie
x-frame-options →SAMEORIGIN
I tried the following example API with my client and it worked:
https://jsonplaceholder.typicode.com/todos/1
So something about djangorestframework and my client must be incompatible.
Solution: needed to add Cross Origin Resource Sharing (CORS)
The Problem here was, that Browsers prevent Javascript from reaching out to other domains according to the Same origin Policy.
The default workaround for this in Django, is "django-cors-headers".
To install it:
pip install django-cors-headers
Then it can be activated in the settings.py
Writing:
INSTALLED_APPS = (
##...
'corsheaders'
)
MIDDLEWARE_CLASSES = (
'corsheaders.middleware.CorsMiddleware',
#...
)
CORS_ORIGIN_ALLOW_ALL = True
You do not seem to query a valid route, perhaps try following:
async componentDidMount() {
try {
const res = await fetch('127.0.0.1:8000/api/questions/?format=json');
const data = await res.json();
this.setState({
data
});
console.log(this.state.data)
} catch (e) {
console.log(e); //SyntaxError: "JSON.parse: unexpected character at line 1 column 1 of the JSON data"
}
}

Categories

Resources