How to do a HTTP head request in next.js - reactjs

I want to achieve the same done here but in next.js.

Next.js provides methods to fetch data from a server and using them as props. I don't know whether you want to use it before rendering a page (like getServerSideProps) or when, for example, you click a button, but I suppose its the first case.
My personal preference when doing requests, is axios, so I will use it in this example:
export async function getServerSideProps({ req, res }) {
// Here is where we make the request
const result = await axios({
method: 'HEAD', // here is where we declare that we want to use the HEAD method
url: "your server url", // this is the url where we want to send the request
headers: {} // if you want to add custom headers, you can do it here
})
// Here we are logging the result of the request
console.log(result)
}
You can refer to the next.js documentation on data fetching and the axios documentation
Have a great day and I hope you succeed on your projects

Related

Django / React - Production API URL routing issues

I have a backend Django REST API that also helps serve my React frontend. I currently have an issue with my API requests url paths to my Django API in production for every page except my home page...
API URL's that work:
I'm able to visit my home page, within my home page, I have a GET request to my API which works great and loads data as expected. This is the only working GET request of my website because the API URL path is correct to my urlpatterns syntax.
API URL's that DON'T work:
The issues arise when I visit a page OTHER than the home page of my React app. My API requests to Django on other pages are using the wrong URL path according to my network panel (they are also responding with index.html), which has me believe I set up my django URLs wrong.
Please checkout my configuration below:
main urls.py:
def render_react(request):
return render(request, "index.html") #<---- index.html from React
urlpatterns = [
path('auth/', include('drf_social_oauth2.urls', namespace='drf')),
path('admin/', admin.site.urls),
path('api/', include('bucket_api.urls', namespace='bucket_api')),
path('api/user/', include('users.urls', namespace='users')),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
urlpatterns += [
re_path('',render_react) #<---- Serving React index.html
]
Here is an example of the issue:
When I visit this subpage URL:
https://mywebsite.com/try-demo/ra4r7n7mdb
A GET request should be firing off too this URL:
https://mywebsite.com/api/demo/ra4r7n7mdb
However instead of sending the request to the correct URL above, it's sending to this url:
https://mywebsite.com/try-demo/api/demo/ra4r7n7mdb
This is the same problem for other parts of my website that are requesting data from my django api. So when I visit my login page (https://mywebsite.com/login), and enter my details to request an authentication token. The request for the token should be:
https://mywebsite.com/auth/token/
but instead its requesting the data through this:
https://mywebsite.com/login/auth/token/
How to fix this?
my url patterns has a catch all request, my react is then able to 404 pages that don't exist. The only problem I have is how my React app is requesting data to my API in production. (again the API request on my homepage works fine) Why are my other requests appending the first URL path of my React router URL's?
I don't want to clog this post with code, so please let me know what other information I should present here to help solve this problem?
UPDATE
I have solved the API request issues to my server. The paths are now correct according to the network panel. However, the issue still remains where I seem to be only getting my index.html as the response for these API requests (they should be data responses, not index.html)
Here is my catch all regex for Django
re_path(".*/", render_react),
re_path(r"^$", render_react)
NEW EDIT
I am now able to get one of my API data requests to respond with JSON data (as should be expected)
Here is the URL of the API request that works:
https://mywebiste.com/api/demo/idoyem1l4k/
These still don't work:
https://mywebsite.com/api/demo/tabledata/idoyem1l4k
https://mywebsite.com/api/demo/graphdata/idoyem1l4k
How I make requests:
import axios from 'axios';
const baseURL = `https://mywebsite.com/api`;
const axiosInstance = axios.create({
baseURL: baseURL,
timeout: 9000,
headers: {
Authorization: 'Bearer ' + localStorage.getItem('access_token'),
'Content-Type': 'application/json',
accept: 'application/json',
},
});
export const getData = async (dispatch, slug, cancelToken) =>
{
try
{
console.log('fired demo request')
const response = await axiosInstance.get("demo/graphdata/" + slug, { cancelToken });
dispatch({ type: 'FETCH_SUCCESS', payload: response.data });
} catch (err)
{
if ('isCancel' in err && err.isCancel())
{
return;
}
dispatch({ type: 'FETCH_ERROR' });
}
}
How can I return the actual data requested instead of my index?
It makes sense, that it always returns the index.html. Your catch all regex prevents your API calls to be called, so it always resolves to render_react. I think you have 3 options.
You try to put the catch-all patterns to the bottom of all urlpatterns - I'm not sure how reliable this is though
You do not catch all by deleting re_path(".*/", render_react), and explicitly name every react page you want to use
You change the catch-all regex to exclude your Django apps with something like re_path("(?!api).*/", render_react),
I would choose option 2, as it gives you most control of your urls

HERE Geocoding API - not working inside my React app

I have a React app in which I use the HERE Geocoding API. I have an axios request to retrieve latitude and longitude and it does not work as well as expected. The request is not working inside my app
return axios.get(`https://geocode.search.hereapi.com/v1/geocode?q=${address}&apiKey=myAPIKey`)
I have a 401 error. Bearer token invalid. Bearer missing or bearer value missing. If I open a new tab in my browser and paste the url https://geocode.search.hereapi.com/v1/geocode?q=${address}&apiKey=myAPIKey it works fine and I get the result I need.
I tried using the Authorization header
const config = {
headers: {
'Accept': 'application/json',
'Authorization': `apiKey myAPIKey`,
}
};
return axios.get(`https://geocode.search.hereapi.com/v1/geocode?q=${address}&apiKey=myAPIKey`,config)
In the Authorization header, I tried with Bearer and Basic instead of apiKey
documentation HERE API
In the documentation about how to create an API Key and how to use it, the only thing I need to do is what I have already done. I have created a project, an API Key and I use it in my request.
HERE Geocoding API Key
I don't know how the HERE api works but the error message is probably the answer you are looking for.
You are likely to provide the api key via the Authorization header with your request. Read about the header on MDN
You just need to pass your API key in the link as a parameter.
Just sign up and you can get your API key.
https://developer.here.com/sign-up
The code should be like this.
return axios.get(`https://geocode.search.hereapi.com/v1/geocode?q=${address}&apiKey=${HERE_MAP_API_KEY}`,config)
The latest request would look like this.
axios.get(`https://geocoder.ls.hereapi.com/search/6.2/geocode.json?languages=en-US&maxresults=${maxResults}&searchtext=${query}&apiKey=${HERE_MAP_API_KEY}`)
.then(res => {
const data = res.data
console.log(data)
})
.catch(err => console.log(err))

Get cookie/localStorage value in nextjs API request

I'm trying to get cookie or localStorage value in my API request. When I'm trying to access localStorage I get error that localStorage is not defined, cookies are undefined, I tried my luck with AsyncLocalStorage, but I'm getting error that window is undefined. There is any way to get saved value in this asynchronous function?
import AsyncLocalStorage from '#createnextapp/async-local-storage'
export default async (req, res) => {
try {
let data = await AsyncLocalStorage.getItem('#key')
console.log(data)
}catch(error){
console.log(error)
}
}
This is expected. When you process the data in your API it is actually running in the server. Localstorage, and cookies however are browser based storage (This is also why window is undefined, servers don't have windows). As a result they are not available to the API to leverage. Instead when you make the API request you need to add the data into a header which can then be parsed on your server.
Setting a header on your request:
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/setRequestHeader
From there you should be able to read the headers through:
(req, res) => {
// look at all these great headers we have
const { headers } = req;
}

send data, url, and method to axios as arguments

I am trying to make custom request with axios and pass the method, url and body as arguments like that
const response = await axios({ url, body, method });
but the body doesnot reach to the backend. what is the right way to send data like that?
The config property you're searching for is called data not body. Rename your variable to data and pass it or don't use the object shorthand operator and rename it to data. Like this:
const response = await axios({ url, data: body, method });
In the axios documentation is a list of all available properties.

Fetch GET request hitting .catch() on anything but 200 response

I have a redux store set up with actions to handle loading accounts. The action calls a service like so:
const requestOptions = {
method: 'GET',
headers: authHeader()
};
return fetch(`http://localapi.co.uk/api/account/load/${account_id}`, requestOptions)
.then(handleResponse)
.then(account => {
if(account.account.id) {
localStorage.setItem('account', JSON.stringify(account))
}
return account;
})
.catch(redirectToLogin)
Handle response is simply a function that checks the .status and .ok properties of the response and either displays an error or logs out if the response status is 401. This works perfectly fine for POST requests. When I hit my login route, any response hits the first .then(handleResponse) and deals with it.
When I send a GET request instead like above 404s, 401s, 500s.. etc all skip the .then(handleResponse) and instead jump to my catch. The problem that causes is that because catch doesn't actually give me a response object to work with I can't check the status - I want to do different things depending on whether the get was a 401 (I want to logout) or a 500 (I want to display a user error stating what went wrong) for example.
Is there a solution that will allow me to get a response or stop my GET requests hitting the .catch and instead hit the response handler I've written?
I'm using:
a Laravel 5.7.20 back-end
a React 16.7.0 front-end
running local node server with npm start
How about having a clean async/await function. Waiting till you JSON data becomes ready and then having the rest of your if logic or returning the account object from the function and moving the rest of the logic to the caller function. Something like this:
async myFunc({ account_id}) {
const url = `http://localapi.co.uk/api/account/load/${account_id}`;
const response = await fetch(url, { headers: headers: authHeader() });
const account = await response.json();
// return account (recommended);
// Place your if logic here (not recommended because its not clean)
}

Resources