Hello Guys I am learning NextJs from a tutorial. There is a link to update categories in which the instructor is using axios.post request in getInitialProps. I am confused why not use axios.get request because aren't we using getting the initial props to populate the page. Here is the code
Update.getInitialProps = async ({ req, query, token }) => {
const response = await axios.post(`${API}/category/${query.slug}`);
return { oldCategory: response.data.category, token };
};
export default withAdmin(Update);
I get this error if I use axios.get enter image description here
Related
I'm working on a Nextjs app and I'm using Laravel api for auth and other things.
So I was searching about the best way to store the token that i will get when I sign a user in or sign him up from that Laravel external api and as I found storing it via httponly cookie is the best way and that's what I did using nextjs api routes to store it there.
I create 3 api routes in /api directory for loging the user in and up and out.
but now I'm facing an issue which is how to send this token on each request that i'm sending on client side to that api.
for now I'm using getServerSideProps to get the token and then send it by props to the needed component but this is solution is redundant and not handy at all.
I'm using getServerSideProps just to get it on any page that need to communicate with backend.
so is there any way to forward the token on each request without the need to get the token from server side and send it to client side?
or do u think there is a better way to store the token in somewhere else?
If you have a httpOnly cookie and you don't want to expose it to the client-side, I don't suggest to pass it in getServerSideProps as prop to the component. This will expose your token and will have the risk of scripts accessing the cookie. If the cookie is HttpOnly, it means it cannot be accessed through the client-side script.
Instead, you can create a NextJS api and access your token there. Then call that api in your app.
This is an example of how to access the cookie in nextjs api:
// src > pages > api > endpoint.js
export default async function (req, res) {
// assuming there is a token in your cookie
const token = req.headers.cookie.token;
// Attach the token to the headers of each request
const fetchWithToken = (url, options = {}) => {
options.headers = options.headers || {};
options.headers.Authorization = `Bearer ${token}`;
return fetch(url, options);
};
// Your API logic here
// ...
}
Now in your component in client-side, you can easily the new endpoint in /api/endpoint/ instead of calling the API with the token. In this method, you will never expose the token to the browser:
import { useState, useEffect } from 'react';
const MyComponent = () => {
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
const res = await fetch('/api/endpoint');
const data = await res.json();
setData(data);
};
fetchData();
}, []);
// Your component logic here
// ...
};
export default MyComponent;
I am using axios to make an api call to an api found on Apihub for a next JS app.
here is the code for the function to make the call to provide a list of property JSON objects.
export const baseUrl = "https://zillow56.p.rapidapi.com"
export const fetchApiListsingsCustom = async (url) => {
const { data } = await axios.get((url), {
method: 'GET',
headers: {
'X-RapidAPI-Key': '328713ab01msh862a3ad609011efp17e6b4jsn0e7112d5ee9a',
'X-RapidAPI-Host': 'zillow56.p.rapidapi.com'
}
});
data.then((res) => {
console.log(res);
})
.catch((error) => {
console.error(error);
});
return data.json();
}
When rendering the page I'm attempting to inject the response's data to dynamically create a list of apartment listings.
I'm trying to use getServerSideProps so that the data is already available by the time a user requests the page. After fetching the data, I want to also print them in the terminal to validate it's success.
export default function Home({ propertiesCustomdata })
export async function getServerSideProps() {
const propertiesCustom = await fetchApiListsingsCustom(`${baseUrl}`)
const propertiesCustomdata = propertiesCustom.json()
return {
props: {
propertiesCustomdata
}
}
}
The problem is, I seem to be getting a 404 error from the axios call, before the page gets a chance to load. When I access this I get a 404 error but I also manage to receive some contents of the call the API was to make.
My apologies if this is unclear, but this is all I know to report on this so far.
Studying async and await, fetch, and axios. Very confusing.
I'm playing around with reactQuery in a little demo app you can see in this repo. The app calls this mock API.
I'm stuck on a an issue where I'm using the useQuery hook to call this function in a product API file:
export const getAllProducts = async (): Promise<Product[]> => {
const productEndPoint = 'http://localhost:5000/api/product';
const { data } = await axios.get(productEndPoint);
return data as Array<Product>;
};
In my ProductTable component I then call this function using:
const { data } = useQuery('products', getAllProducts);
I'm finding the call to the API does get made, and the data is returned. but the table in the grid is always empty.
If I debug I'm seeing the data object returned by useQuery is undefined.
The web request does successfully complete and I can see the data being returned in the network tab under requests in the browser.
I'm suspecting its the way the getAllProducts is structured perhaps or an async await issue but can't quite figure it out.
Can anyone suggest where IO may be going wrong please?
Simply use like this
At first data is undefined so mapping undefined data gives you a error so we have to use isLoading and if isLoading is true we wont render or map data till then and after isLoading becomes false then we can render or return data.
export const getAllProducts = async (): Promise<Product[]> => {
const productEndPoint = 'http://localhost:5000/api/product';
const res= await axios.get(productEndPoint);
return res.data as Array<Product>;
};
const { data:products , isLoading } = useQuery('products', getAllProducts);
if(isLoading){
return <FallBackView />
}
return (){
products.map(item => item)
}
I have managed to get this working. For the benefits of others ill share my learnings:
I made a few small changes starting with my api function. Changing the function to the following:
export const getAllProducts = async (): Promise<Product[]> => {
const response = await axios.get(`api/product`, {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
});
return response.data as Product[];
};
I do not de-construct the response of the axios call but rather take the data object from it and return is as an Product[]
Then second thing I then changed was in my ProductTable component. Here I told useQuery which type of response to expect by changing the call to :
const { data } = useQuery<Product[], Error>('products', getAllProducts);
Lastly, a rookie mistake on my part: because I was using a mock api in a docker container running on localhost and calling it using http://localhost:5000/api/product I was getting the all to well known network error:
localhost has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present...
So to get around that for the purpose of this exercise I just added a property to the packages.json file: "proxy":"http://localhost:5000",
This has now successfully allowed fetching of the data as I would expect it.
I'm learning Next.js and run into a problem. I was following a tutorial on youtube to make a google clone with the next.js + tailwind. So the problem is when I add export async function getServerSideProps() I get an error invalid JSON response body. Reason: Unexpected token < in JSON at position 0
Seems I am doing everything exactly as the instructor but he doesn't get any error.
export async function getServerSideProps(context) {
const useDummyData = false;
const data = await fetch(
`https://developers.google.com/custom-search/v1?
key=${API_KEY}&cx=${CONTEXT_KEY}&q=${context.query.term}`
).then((response) => response.json());
return {
props: {
results: data,
},
};
}
I have some problems with the auth process on Nextjs project. From the example, it stores the token in cookies, but in checkLoggedIn.js it queries DB instead of get the token from cookie.
I would like to get the token from cookie or localstorage in getInitialProps, but in getInitialProps, it can NOT see localstorage because it's still in server side. Is there any better way that I could auth user before component render?
Not sure is it possible to get the token from getToken in apollo client.
My current code is
class DashBoard extends React.Component {
constructor(props) {
super(props)
}
componentDidMount () {
const decodeToken = verifyToken(localStorage.getItem('KEY'));
if (!decodeToken.mail) {
Router.push('/login');
} else {
this.props.loginSuccess(decodeToken.name, decodeToken.mail);
}
}
render () {
return (<div></div>)
}
}
Thank you
I solved this by using nookies. It works both server side (for getInitialProps) and client side in Next.js
Here is what I did to solve it after few days of research (honestly, not the best documentation around)
In the getInitialProps, I took the headers from the requests and copied them over in my fetch request.
Profile.getInitialProps = async ({ req }) => {
const headers = { ...req.headers }
const url = `http://localhost:3000/api/profile`
const data = await fetch(url, { headers }).then(res => res.json())
return { data }
}
Keep in mind that this only works on the server. For the client, you can just pass {credentials: 'include'} to fetch