React Restful api is making problem with json - javascript

I have been trying all sort of things but this is first time this happens. I spend days on google and youtube to find something but nothing works nor one opinion nor many all together or some kind of combinations.
import React, { Component } from "react";
class App extends Component {
componentDidMount() {
fetch("../public/data.json")
.then(res => res.json())
.then(data =>
console.log(data);
);
}
render() {
return <div></div>;
}
}
export default App;
And the error is:
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0

If you want to get data from a local json file you don't need to use fetch method. You can simply import your file.
You thus don't need to use fetch method in your componentDidMount. In the future if you want to use fetch method you have to remember that fetch takes an url. I provide you a valid url to show you an example.
import React, { Component } from "react";
import json from "../public/data.json";
class App extends Component {
componentDidMount() {
fetch("https://randomuser.me/api/?results=10")
.then(res => res.json())
.then(data =>
console.log(data);
);
console.log(json); // print your Json file
}
render() {
return <div></div>;
}
}
export default App;

You are giving your fetch call a relative path to a file. This needs to be your API endpoint.
componentDidMount() {
fetch("../public/data.json") // this needs to be a url
.then(res => res.json())
.then(data =>
console.log(data);
);
}
if you have the JSON file locally already and just want your React Component to have access to it, then just import it import jsonData from "../public/data.json"

You can simply use 'require' to import your JSON file, if it is local.
E.g.: const data = require('../public/data.json'). console.log(data) will return the entire JSON object.
Edit: One thing to remember is that require() will always cache the content of the loaded module (or file, in this case). The next time require() is called again, it will restore it from the cache instead of reading it again.

On a contrary with other answers, fetch("../public/data.json") is a valid url. The only problem is that it will take current url in the browser, go one level up (e.g. remove content after last /) and append public/data.json, then try to fetch the resource. So the error Unexpected token < in JSON at position 0 comes from trying to parse html (most likely <!doctype html> as json

Related

Invalid hook call trying to make an axios get request in react

I'm recreating a simple weather app with react and am having a lot of trouble creating a very simple API call. I've tried a plethora of methods on here, youtube, etc and continuously get errors. The current code I have is:
import Axios from 'axios';
import { Home } from '../components/Home'
import React, {useState, useEffect} from 'react'
var weatherApiRootUrl = 'https://api.openweathermap.org';
var weatherApiKey = 'd91f911bcf2c0f925fb6535547a5ddc9';
//function to generate weather URL. fetches lat/lon and creates new url
function GetWeatherUrl(loc){
const [weatherLink, setWeatherLink] = useState("");
const getCoordinates = () => {
Axios.get(`${weatherApiRootUrl}/geo/1.0/direct?q=${loc}&limit=5&appid=${weatherApiKey}`).then(
(response)=>{
console.log(response);
setWeatherLink(`${weatherApiRootUrl}/data/2.5/onecall?lat=${response.data.lat}&lon=${response.data.lon}&units=imperial&exclude=minutely,hourly&appid=${weatherApiKey}`);
}
);
};
return(
<div>
{weatherLink}
</div>
);
}
export{
GetWeatherUrl
}
The purpose of this file is just to use the user input (a city name designed by variable loc) to fetch lat/lon coordinates of the inputted city as that data is needed for the second link that fetches weather information. The user input is handled from another component and works fine.
All I intend for this code to do is fetch latitude and longitude data using loc and use those numbers to generate the new link that fetches weather data. The weather data will be done with a different api call on another file. The working method of this current file should be useable for the future file meant to fetch weather so this is kind of two birds in one stone.
I need the weatherLink generated to be able to be exported to do this so I would really prefer a solution allowing that please. I originally was going to just export the raw lat/lon data and use them for the call in the new file as how I did with loc here but I decided returning a completed link as a string would maybe be easier. Really would appreciate someone's help on this it's been frustrating me for way longer than it should!
Not really needed but here's the non-react version of the site if it helps: https://giovannimalcolm.github.io/weather-dashboard/
This can be easily solved without needing to use React at all, since it is not a component and doesn't have any rendering logic in itself per se:
import Axios from 'axios';
const weatherApiRootUrl = 'https://api.openweathermap.org';
const weatherApiKey = 'd91f911bcf2c0f925fb6535547a5ddc9';
export async function GetWeatherUrl(loc) {
const response = await Axios.get(`${weatherApiRootUrl}/geo/1.0/direct?q=${loc}&limit=5&appid=${weatherApiKey}`);
return `${weatherApiRootUrl}/data/2.5/onecall?lat=${response.data.lat}&lon=${response.data.lon}&units=imperial&exclude=minutely,hourly&appid=${weatherApiKey}`;
}
Then in places where you need to use the weather URL, you need to remember that GetWeatherUrl returns a promise, so you've got to await it (or handle it like any other promise):
const myFn = async () => {
const weatherUrl = await GetWeatherUrl(loc);
const weatherUrlData = await Axios.get(weatherUrl);
};
myFn();

getServerSideProps proper usage?

I have recently been trying to create a web app with NextJS. I know some basics in web development but I was a little lost when using NextJS as I didn't do any React either before.
I've tried fetching data from an API and using this data in my page. I struggled a bit but in the end I got it working with the help of getServerSideProps.
My question is, how could I use getServerSideProps multiple times in my application so that I can fetch many other routes ? I've tried using getServerSideProps in a different file, using its response in a function that I then export as a component and use it so I can "get components of getServerSideProps responses" if it makes sense, but had many different errors when trying to do so.
Could someone explain how it actually works and how I could resolve my issue, and if it doesn't work that way, how could I make it work?
Here's an example using Coinbase's API :
import { useState } from 'react'
import fetch from 'isomorphic-fetch'
export const getServerSideProps = async () => {
const res = await fetch('https://api.coinbase.com/v2/prices/ETH-USD/buy')
const data = await res.json()
return {
props: {
ethprice: data
}
}
};
I then use "ethprice" in my Home function such as :
export default function Home({ ethprice }) {
return (
[page content, divs, text etc...]
{etherprice.data.amount}
Thanks!
getServerSideProps is specific to that particular file, you can't just use it in any way you want.
const Example = (props) => {
return // this is your component
}
export const getStaticProps = async () => {
// this will provide props specifically for 'Example'
}
More than that getStaticProps will only be run once on static page generation and never again, along with fetching the props for that particular component only. So you can't get live data from it, only data required to generate the page (like page title).
You can have a look at getServerSideProps if you're looking for something more dynamic that can fetch props at runtime. After that you can pass those props down to children if you need to.

I use next.js and i try to do a single post page

i use nextjs and i fetch some dummy data on home and now i want to make a page for each post that i got on home i made it but i feel is not a good code so if someone can healp me clear some things and also learn more on next i will appreciate this a lot. here is the code:
import { useRouter } from 'next/router'
import {useEffect} from 'react'
const post = () => {
const router = useRouter()
const pid = router.query.pid
async function getdata (){
if(pid){
const res = await fetch(`https://jsonplaceholder.typicode.com/posts/${pid}`)
const data = await res.json()
console.log(data)
}
}
useEffect(() => {
getdata()
}, [pid])
return(
<p>wasd{pid}</p>
)
}
export default post
I suppose you're talking about making components or each different route for each different data.
FIRST CASE-If we talk about the first case you can have a folder called components outside your pages for folder and make components there and map that component depending on your data or whatever.
SECOND CASE-If you want to have a different route [filename].js is the way to go this represents lets say localhost:3000/foldername/:filename. So you can do stuff from here. I'd suggest reading nextjs docs for more info on this routing.

Nextjs getInitialProps blocked the page rendering in client side?

Since I like to add SSR to my upcoming project to improve SEO, I would like to try out next. What I want is that only use SSR for the initial page, and the rest of navigations in the site will be client side rendering. I see the getInitialProps fit the most in this case, accordingly the documentations.
As my understanding, getInitialProps is run in server for the initial page rendering, and is run in the browser when navigating using next/link. The issue I found is that the getInitialProps seems to block the page rendering. (i.e. page changed/rendered after getInitialProps is completed)
import axios from 'axios'
function Posts(props) {
return (
<div>
<div>Posts:</div>
<div>
{JSON.stringify(props)}
</div>
</div>
)
}
Posts.getInitialProps = async (context) => {
const response = await axios.get('https://jsonplaceholder.typicode.com/posts');
// Wait longer to see the effect
// await (new Promise((resolve) => {
// setTimeout(resolve, 5000)
// }))
return {
props: {
posts: response.data
}
}
}
export default Posts;
How can I do it like in pure React, render the jsx first, then fill in the props? (the execution JSON.stringify(props) might be ignored at first)
Also, in next 9.3, the team introduced getServerSideProps, which is recommended over getInitialProps. How can they be comparable when they are not the same that getServerSideProps will on run in server?
Based on your comments, you want to do the fetch on the server, on the initial page load. However, if navigating between pages you don't want rendering to block while waiting for getInitialProps to return.
One solution is to check if you're on the server, and do the fetch in getInitialProps. If on the client, don't do the fetch in getInitialProps and instead fetch using useEffect in your render method.
import {useEffect} from 'react'
import axios from 'axios'
const isServer = () => typeof window === 'undefined'
const getPosts = () => {
return axios.get('https://jsonplaceholder.typicode.com/posts')
.then(response => response.data)
}
function Posts({posts}) {
const [renderPosts, setRenderPosts] = useState(posts)
useEffect(() => {
if(posts === null) {
getPosts()
.then(setRenderPosts)
}
}, [])
return (
<div>
<div>Posts:</div>
<div>
{JSON.stringify(renderPosts)}
</div>
</div>
)
}
Posts.getInitialProps = async (context) => {
if(isServer()) {
return {
posts: await getPosts(),
}
}
else {
return {
posts: null,
}
}
}
export default Posts
By the way, you may be tempted to use getServerSideProps here, since it is only called if rendering on the server. However, when a page using getServerSideProps is rendered, it will actually make a call to the server to get data from getServerSideProps, even if you're navigating using next/link. From the Next.js 9.3 blog post:
When navigating between pages using next/link instead of executing getServerSideProps in the browser Next.js will do a fetch to the server which will return the result of calling getServerSideProps.
This would still cause the blocking issue you're wanting to avoid.
One final note, this might not be an idiomatic solution. There may be a more "standard" solution. I just wasn't able to find one. You could likely also use a wrapper around your page component that could do all of this in a more consistent way. If you use this pattern a lot, I'd recommend that.

Why am I not able to use promise in my basic react app?

I am fairly new to react and I was experimenting on axios get requests . So What I am trying to do is that I have a json file in my public folder and I am making a get axios request to the location of that file and then I am printing the result in an array .
The first method worked pretty smoothly . A demo of the function is given below
The output is given below:
And as evident , this approach worked pretty fine.
However I also made a class named Fetch inside a service.js file . This class had a method named fetch which used axios to make a get request.
The demo of this class is given below:
import React from 'react';
import axios from "axios";
class Fetch extends React.Component
{
constructor()
{
super();
}
fetch()
{
console.log("Hi i am in fetch of service....");
axios.get('./config.json').then(response=>{
var x=response.data;
console.log("----------------------------------------->"+JSON.stringify(x));
return x;
},(err)=>{
return err;
})
}
}
export default Fetch;
I imported this class in another js file and made an object of this class to call the fetch method.A demo of my usage is given below:
However when I tried to do this , I got the following error:
What am I doing wrong ? If it worked for the first time , then why is this not working now?
You are receiving that error because nothing is returned from Fetch.fetch(), let alone a promise.
You are trying to call .then() on a void function, so you will not be able to access the response.
In your Fetch class, return the axios request from the fetch() function:
fetch() {
return axios.get('/config.json').then(response => {
// your code
})
}

Categories

Resources