GraphQL dynamic page API call - reactjs

So I am building a dynamic lesson page with GraphQl and React.
I built a custom hook, and I do not know how to pass the ID up to the config data.
This is my hook that I made.
This is my first time working with GraphQL
import axios from 'axios'
import { useState, useEffect } from 'react'
const { REACT_APP_SPACE_ID, REACT_APP_CDA_TOKEN } = process.env
var data = JSON.stringify({
query: `{
lesson(id: ${id}){
shortTitle
shortDescription
}
}`,
variables: {},
})
var config = {
method: 'post',
url: `https://graphql.contentful.com/content/v1/spaces/${REACT_APP_SPACE_ID}`,
headers: {
Authorization: `Bearer ${REACT_APP_CDA_TOKEN}`,
'Content-Type': 'application/json',
},
data: data,
}
export default function GetLesson(id) {
let [data, setData] = useState()
useEffect(() => {
getContent()
}, [])
const getContent = async () => {
await axios(config)
.then(function (response) {
setData(response.data.data.lesson)
})
.catch(function (error) {
console.log(error)
})
}
return { data }
}

Related

React MERN App - Not passing ID to fetch api

I am creating a react app with full crud functionality. It allows users to create job postings and i wanted to click on a specific job to view more details.
I am having trouble as everytime i try to click a "job" it says that ID is undefined specifically:
show function called with id: undefined
SyntaxError: Unexpected end of JSON input
My app currently displays the list of all jobs and creates.
I already confirmed the following:
Made sure the backend server is running and listening on port 3001.
Verified that the endpoint i am trying to fetch actually exists. Tried on postman
Made sure that my frontend code is using the correct URL to make requests to the backend.
I am using hooks and functions.
DetailsPage.js
import styles from './DetailsPage.module.css';
import React, { useState, useEffect } from 'react';
import jobsService from '../../utils/jobsService';
export default function DetailPage(props) {
const [job, setJob] = useState({});
const [isLoading, setIsLoading] = useState(true);
const { id } = props.match?.params || {};
useEffect(() => {
const fetchData = async () => {
try {
const { data } = await jobsService.show(id);
setJob(data);
} catch (error) {
console.log(error);
} finally {
setIsLoading(false);
}
};
fetchData();
}, [id]);
return (
<>
{isLoading ? (
<div>Loading...</div>
) : (
<div className={styles.list}>
<div className={styles.Grid}>
<h3>{job.title}</h3>
<p>{job.description}</p>
</div>
</div>
)}
</>
);
}
jobsService.js
async function getAll(){
const response = await fetch('http://localhost:3001/api/jobs')
const data = await response.json()
return data
}
async function create(item) {
try {
const response = await fetch('http://localhost:3001/api/jobs/create', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(item)
});
return await response.json();
} catch (error) {
console.error(error);
}
}
async function show(id) {
console.log("show function called with id:", id);
return fetch(`http://localhost:3001/api/jobs/${id}`, {
method: 'GET',
headers: {
'Content-type': 'application/json',
},
})
.then(res => res.json());
}
export default {
getAll,
create,
show,
}
destruct id form empty object ?
instead this
const { id } = props.match?.params || {};
test this
const { id } = props.match?.params || {id: 0};
or use ternary operator in function calling
or
async function show(id = 0) {
console.log("show function called with id:", id);
return fetch(`http://localhost:3001/api/jobs/${id}`, {
method: 'GET',
headers: {
'Content-type': 'application/json',
},
})
.then(res => res.json());
}

converting custom react function to async

I made this custom hook.
import axios from "axios";
import Cookies from "js-cookie";
import React from "react";
const useGetConferList= () => {
let token = JSON.parse(localStorage.getItem("AuthToken"));
const Idperson = JSON.parse(Cookies.get("user")).IdPerson;
const [response, setResponse] = React.useState();
const fetchConfer= (datePrensence, idInsurance, timePrensence) => {
axios({
method: "post",
url: `${process.env.REACT_APP_API_URL_API_GET_ERJASERVICE_LIST}`,
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
data: JSON.stringify({
datePrensence,
idInsurance,
Idperson,
searchfield: "",
timePrensence: parseInt(timePrensence) * 60,
}),
})
.then((r) => {
setResponse(r.data.Data);
})
.catch(() => alert("NetworkError"));
};
return { fetchConfer, response };
};
export default useGetConferList;
as you can see I export the fetchConfer function. but I want to make it async. for example, calling the function and then doing something else like this:
fetchConfer(Date, Time, Id).then((r) => {
if (search !== "") {
window.sessionStorage.setItem(
"searchList",
JSON.stringify(
r.data
)
);
}
});
as you can see in non async situation, I can't use then.
You can try this
const fetchConfer = async (datePrensence, idInsurance, timePrensence) => {
try {
const response = await axios({
method: "post",
url: `${process.env.REACT_APP_API_URL_API_GET_ERJASERVICE_LIST}`,
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
data: JSON.stringify({
datePrensence,
idInsurance,
Idperson,
searchfield: "",
timePrensence: parseInt(timePrensence) * 60,
}),
})
setResponse(response.data.Data);
// need to return data
return response.data.Data
} catch(error) {
alert("NetworkError")
}
};
use the function in another async function
const someAsyncFunc = async () => {
// try catch
const r = fetchConfer(Date, Time, Id)
if (search !== "") {
window.sessionStorage.setItem(
"searchList",
JSON.stringify(
r.data
)
);
}
...
or use it how you are currently using it
Hope it helps

How to pass parameter in axios instance dynamically?

I am trying to pass token that comes from Redux store in an axios instance(useRequest). I want to pass the token while I am calling the instance
requestMethod.js
import axios from "axios";
const BASE_URL = "http://localhost:5000/e-mart/";
//Declaring a function to pass the Token dynamically.
export const userRequest =(TOKEN) => axios.create({
baseURL: BASE_URL,
header: { token: `Bearer ${TOKEN}` }, // Here the token comes dynamically
});
Products.js
import { userRequest} from "../requestMethods";
import { useDispatch, useSelector } from "react-redux";
const {accessToken} = useSelector((state) => state.user.currentUser);//accessing token from redux store
useEffect(() => {
const abortController = new AbortController();
const getProdcuts = async () => {
try {
const res = await publicRequest.get(
`products`,
{ signal: abortController.signal } // Here is where i want to pass the token from redux stroe
);
setProducts(res.data);
} catch (err) {
console.log(err.message);
}
};
getProdcuts();
return () => {
abortController.abort();
};
}, []);
If token is dynamic, don't pass it while create axios instance
// Axios instance
export const userRequest =(TOKEN) => axios.create({
baseURL: BASE_URL
})
// how to call with different dynamic tokens
await API.patch('products',
{ signal: abortController.signal },
{
headers: {
token: `Bearer ${TOKEN}`,
},
},
);

I am trying to fetch users using Github API, but it says the token is wrong

I am try to fetch users information using github API
import React, { useEffect } from "react";
function UserResults() {
useEffect(() => {
fetchUsers();
}, []);
const fetchUsers = async () => {
const response = await fetch(`${process.env.REACT_APP_GITHUB_URL}/users`, {
headers: {
Authorization: `token ${process.env.REACT_APP_GITHUB_TOKEN}`,
},
});
const data = response.json();
};
return <div>Hello</div>;
}
export default UserResults;
And here is what I put in my env:
REACT_APP_GITHUB_TOKEN="<token>"
REACT_APP_GITHUB_URL = "https://api.github.com"
I am sure the token is correctly generated and copied.
But it seems I can't fetch the data due to some "JSON" error as it shows in the console like this.
Can anyone offers any help with this?
You need to await response.json() and update your header request
import React, { useEffect } from "react";
function UserResults() {
useEffect(() => {
fetchUsers();
}, []);
const fetchUsers = async () => {
const response = await fetch(`${process.env.REACT_APP_GITHUB_URL}/users`, {
headers: {
'Authorization': `token ${process.env.REACT_APP_GITHUB_TOKEN}`,
'Content-Type': 'application/json',
'Accept': 'application/json'
},
});
const data = await response.json();
};
return <div>Hello</div>;
}
export default UserResults;

Fetching data in React's useEffect() returns data “undefined”

I am trying to fetch data in reactjs with help of use effect hook but after accessing that in return div it is showing data undefined code is given below for that
import React,{ useEffect } from 'react'
export default function Home() {
useEffect(() => {
fetch("https://lighthouse-dot-webdotdevsite.appspot.com//lh/newaudit", {
method: "POST",
body: JSON.stringify({
"url": "https://piyushsthr.netlify.app",
"replace": true,
"save": false
}),
headers: {
"Content-Type": "application/json; charset=utf-8"
},
credentials: "same-origin"
})
.then(res => res.json()) // this is the line you need
.then(function(data) {
console.log(data.lhrSlim[0].score)
//return data;
}).catch(function(error) {
// eslint-disable-next-line no-unused-expressions
error.message
})
}, )
return (
<div>
<h1>{data.lhrSlim[0].score}</h1>
</div>
)
}
can anyone help me to fix this thing
You cannot directly show the content of the request directly on the UI, to do that either it has to be a prop or be stored in the state, for example you could do this.
import React, { useEffect, useState } from 'react'
export default function Home() {
const [State, setState] = useState("");
useEffect(() => {
fetch("https://lighthouse-dot-webdotdevsite.appspot.com//lh/newaudit", {
method: "POST",
body: JSON.stringify({
"url": "https://piyushsthr.netlify.app",
"replace": true,
"save": false
}),
headers: {
"Content-Type": "application/json; charset=utf-8"
},
credentials: "same-origin"
})
.then(res => res.json()) // this is the line you need
.then(function(data) {
setState(data.lhrSlim[0].score);
}).catch(function(error) {
// eslint-disable-next-line no-unused-expressions
error.message
})
}, )
return (
<div>
<h1>{State}</h1>
</div>
)
}
That way you will be able to store the data from the response directly on the state of the component and be able to show it afterwards.
To display the data from the api add a state in your component.
const [score, setScore] = useState([]);
then set score
.then(function (data) {
setScore(data?.lhrSlim[0]?.score);
})
https://codesandbox.io/s/proud-surf-v9gjb?file=/src/App.js

Resources