nextjs page is showing 404 in server but works in localhost - api

This is a React component in Next.js that implements a search functionality. It uses the useRouter hook from the next/router library to retrieve the search query from the URL and store it in the search variable. Then, the component uses the useState hook to store the search results in the searchData state.
The component calls an async function torHeda in the useEffect hook, which sends a POST request to the endpoint domain + 'api/vb1/search-post' with the search query in the request body. The response is stored in resData , and the searchData state is updated with resData["data"].
The component returns a grid of cards with information about the search results, each card is rendered using the Cards component, and the title, category_name_bn, created_at, image, id, and status of each search result is passed as props to the Cards component. If the searchData array is empty, it will return a message indicating that no results were found. It works in localhost perfectly fine but after deploy to server it shows 404 This page could not be found.
Here is full page code:
import Link from 'next/link';
import {useRouter} from 'next/router';
// import { useRouter } from 'next/router';
import {useState, useEffect} from "react"
import Cards from '../components/GridCards';
import domain from '../cred';
function SearchDetails() {
const router = useRouter();
const search = router.query.search
const [searchData, setSearchData] = useState()
useEffect(()=>{
async function torHeda (){
const data = {
search: search
}
const JSONdata = JSON.stringify(data)
const endpoint = domain + 'api/vb1/search-post'
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSONdata,
}
const response = await fetch(endpoint, options)
const resData = await response.json();
const searchData= resData["data"]
setSearchData(searchData)
}
torHeda()
},[]);
return (
<>
<div className='grid grid-cols-4 mb-4 gap-10 mx-48 my-12 w-full'>
{searchData?.map(pageItem=>{
{console.log(searchData)}
if (searchData !== null) {
return <Cards key={pageItem?.id} title={pageItem?.title_bn} catagory={pageItem?.category_name_bn} time={pageItem?.created_at} imgSrc={pageItem?.image} status={pageItem?.status}/>;
}
})}
</div>
{(()=>{
if(searchData?.length === 0){
return <div key={1} className="h-[10rem] flex justify-start items-center mx-48 md:mx-10"> <h1 key={1} className='text-black text-3xl w-full dark:text-white md:text-base'>দুঃখিত আপনি যা খুঁজছেন তা খুঁজে পাওয়া যায়নি! পুনরায় অনুসন্ধান করুণ।</h1> </div>
}
})()}</>
);
}
export default SearchDetails;

After deleting this page I build the website using command npm run build. After a while I reuploaded the this file and again I rebuild the website.. I tried rebuild many times before but deleing file method worked for me .

Related

vue 3 composition api, passing data and making it reactive

In my component I have a simple select menu with two options ("all", and "Investment"). The idea here is to get an array of data from a composable, and display on screen each row of this data. If I select "all" in the menu it displays all rows, if I select "Investment" it will filter the data and display only those with obj.link == "usa".
Once I fetch the data and bring it into my component, if I console.log the data, it works fine. If I console.log the data after i filter it, I get an empty array.
I have then tried to hard code the data in my component and test the filter function, and it works fine. So the error comes from how I am getting my data and how I try to use it. I have tried to use different hooks such as onMounted, but was unsuccessfull.
Here is a minimalistic sample of my code.
Any suggestion or advice is more than welcome
The composable that fetches the data from my database looks like this:
import {ref} from 'vue'
import { projectFirestore } from '../firebase/config'
import { collection, getDocs } from "firebase/firestore";
const getActorDocs = () => {
const actorDocs = []
const error = ref(null)
const loadActors = async () => {
try {
const querySnapshot = await getDocs(collection(projectFirestore, "actors"));
querySnapshot.docs.map(doc => {
actorDocs.push(doc.data())
})
} catch (err) {
error.value = err.message
console.log(error.value)
}
}
return { actorDocs, error, loadActors}
}
export default getActorDocs
My component:
<template>
<div class="col-2">
<span class="lbl">MA</span>
<select v-model="selectedMA" class="form-select" >
<option value="all">all</option>
<option value="Investment">Investment</option>
</select>
</div>
<p v-for="obj in actorListTest2" :key="obj" :value="obj"> {{obj}} </p>
<template/>
<script >
import {onMounted, onBeforeMount, ref} from 'vue'
import getActorDocs from '../../composables/getActorDocs'
export default {
setup(){
const selectedMA = ref("Investment")
const error = ref(null)
const {actorDocs, loadActors} = getActorDocs()
var actorListTest1 = actorDocs
const actorListTest2 = ref([])
loadActors() // loads actors array into actorDocs
actorListTest2.value = actorListTest1
console.log(actorListTest1) // <----- prints correctly (see image below)
if(selectedMA.value === "all"){
actorListTest2.value = actorListTest1
}else{
actorListTest2.value = actorListTest1.filter(obj => {
return obj.link == selectedMA.value
})
}
console.log(actorListTest2.value) // <----- prints undefined !
return { error, selectedMA, actorListTest2}
}//setup
}
</script>
This is the output of console.log(actorListTest1):
Then this is the output of console.log(actorListTest2) after filtering :
This is a known problem with console.log, it shouldn't be used to debug object values in real time.
actorDocs is not reactive and won't work correctly with asynchronous operations in Vue. Side effects are supposed to be done in lifecycle hooks, e.g.: mounted.
In current state getActorDocs isn't ready to be used with composition API because it's limited to follow promise control flow in order to avoid this race condition:
onMounted(async () => {
await loadActors();
console.log(actorListTest2.value);
});
A correct way to avoid this is to make actorDocs reactive array or a ref:
const actorDocs = reactive([]);
In case there's a need to access filtered value in side effect, e.g. console.log, this is done in a watcher
const actorListTest2 = computed(() => actorDocs.filter(...));
watch(actorListTest2, v => console.log(v));
onMounted(() => {
loadActors();
});

Getting the Plaid Link to Work in my Create React App with Auth0

I had started a project a little while ago and have been busy lately so I have not been able to work on it. I am out of practice with web development because I had recently joined the military. Right now the project consists of a create-react-app app with auth0 integrated. What I am trying to do is get the plaid link integrated into the page it takes you after logging in using auth0. I am requesting help on what code from the plaid docs I use in order for this to work. Their documentation is a little confusing to me, maybe because I'm so out of practice. Any help would be much much appreciated.
https://github.com/CollinChiz/SeeMyCash
Have you taken a look at the Quickstart at https://github.com/plaid/quickstart/? It contains a full React implementation that does this. Here's the relevant excerpt:
// APP COMPONENT
// Upon rendering of App component, make a request to create and
// obtain a link token to be used in the Link component
import React, { useEffect, useState } from 'react';
import { usePlaidLink } from 'react-plaid-link';
const App = () => {
const [linkToken, setLinkToken] = useState(null);
const generateToken = async () => {
const response = await fetch('/api/create_link_token', {
method: 'POST',
});
const data = await response.json();
setLinkToken(data.link_token);
};
useEffect(() => {
generateToken();
}, []);
return linkToken != null ? <Link linkToken={linkToken} /> : <></>;
};
// LINK COMPONENT
// Use Plaid Link and pass link token and onSuccess function
// in configuration to initialize Plaid Link
interface LinkProps {
linkToken: string | null;
}
const Link: React.FC<LinkProps> = (props: LinkProps) => {
const onSuccess = React.useCallback((public_token, metadata) => {
// send public_token to server
const response = fetch('/api/set_access_token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ public_token }),
});
// Handle response ...
}, []);
const config: Parameters<typeof usePlaidLink>[0] = {
token: props.linkToken!,
onSuccess,
};
const { open, ready } = usePlaidLink(config);
return (
<button onClick={() => open()} disabled={!ready}>
Link account
</button>
);
};
export default App;

Trying to consume api using react-native

I created an api with laravel and now i want to be able to consume it using React-native but it's not working at all and I have no clue about it. Here are some code that i think can be helpful to help you try to help me.
That's my api.js file.
import {create} from 'apisauce';
import { AsyncStorage } from 'react-native';
const api = create({
baseURL:'http://127.0.0.1:8000/api',
});
api.addAsyncRequestTransform( request => async () => {
const token = await AsyncStorage.getItem('#PetFinder:token');
if(token) {
request.headers['Authorization'] = `Bearer ${token}`;
}
request.headers['Content-Type'] = `application/json`;
request.headers['accept'] = `application/json`
});
And here is my Login page
import React from 'react';
import { View, Button } from 'react-native';
import api from '../../services/api'
export default function Login() {
async function handleSubmit()
{
const response = await api.post('/login', {
email: 'nowahmst#gmail.com',
password:'123456',
});
}
return (
<View><Button onPress={handleSubmit} title="Login" > </Button></View>
);
}
Back-End is running, I'm able to get the response using postman or insomnia and my route is set to be post as well the api request.

Updating view based on API response

I'm having an issue with showing information in my App.js state object in a child component. Below are the relevant parts. App.js, WeatherDetail is the aforementioned component, and then the response from API request.
App.js
import React from "react";
import openweather from "../api/openweather";
import SearchBar from "./SearchBar";
import WeatherDetail from "./WeatherDetail";
class App extends React.Component {
state = { weather: [], daily: [] };
onSearchSubmit = async zip => {
const currentWeather = openweather.get("/data/2.5/weather", {
params: { zip }
});
const fiveDayForecast = openweather.get("/data/2.5/forecast", {
params: { zip }
});
const [weather, daily] = await Promise.all([
currentWeather,
fiveDayForecast
]);
this.setState({ weather: weather.data, daily: daily.data.list });
};
render() {
return (
<div>
<SearchBar onSubmit={this.onSearchSubmit} />
<WeatherDetail weather={this.state.weather} />
</div>
);
}
}
export default App;
WeatherDetail.js
const WeatherDetail = ({ weather }) => {
return (
<div>
<h1>Today</h1>
<h3>City: {weather.name}</h3>
<h5>Temperature:</h5>
</div>
);
};
>forecast:
base: "stations"
>clouds: {all: 75}
cod: 200
>coord: {lon: -82.54, lat: 40.7}
dt: 1553023267
id: 420031370
>main:
humidity: 45
pressure: 1030
temp: 44.22
temp_max: 46.99
temp_min: 41
name: "Elyria"
Now, weather.name shows up in the view with no problem. If I try to grab any information deeper than that I get an error saying the property is undefined. For example, weather.main.temp is how I thought I would get the temperature but it shows that error. weather.main alone gives an obvious error, but it shows the object I'm trying to access in the message. So I'm confused about how that can be when weather.main.temp also says the property (main) is undefined. Am I trying to access the object incorrectly or is something else set up wrong?
The problem comes with the initial render, before you have received results from the API. The first time WeatherDetail renders, it has the default state, which you've set to state = { weather: [], daily: [] };. This means that on initial render there is no main attribute existing on state.weather. It's just an empty array. The attributes only exist when you populate them on running onSearchSubmit.
I would add some validation in your WeatherDetail component. Something like the below:
const WeatherDetail = ({ weather }) => {
const { name, main } = weather;
return (
<div>
<h1>Today</h1>
<h3>City: { name ? name : ''}</h3>
<h5>Temperature: { main ? main.temp : '' }</h5>
</div>
);
};
That way on initial render if the attributes don't exist you can still render empty strings, and when the state gets populated and the correct attributes exist, it will render the correct content.

How to add React to an Express app?

I'm developing an app using Express and I'd like to run React on the front-end. How should I go about this?
I've seen people adding script tags (using CNDs) to their layout files, others using many npm packages...
What is the easiest way?
ES6 (with Babel) is used, buy you don't have to.
server.js
import "babel-core/polyfill";
import path from "path";
import express from "express";
import React, { DOM } from "react";
import ServerDOM from "react-dom/server";
import Html from "./components/Html";
const server = express();
server.set("port", (process.env.PORT || config.port));
server.use(express.static(path.join(__dirname, "public")));
server.use("/", (req, res, next) =>
{
const html = ServerDOM.renderToStaticMarkup(React.createElement(Html));
res.status(200).send("<!doctype html>" + html);
});
server.get("*", async (req, res, next) =>
{
try
{
let statusCode = 200;
const html = ServerDOM.renderToStaticMarkup(React.createElement(Html));
res.status(statusCode).send("<!doctype html>" + html);
}
catch (e) { next(e) }
});
server.listen(server.get("port"), () =>
{
console.log("\nServer running at localhost:%d\n", server.get("port"));
});
Html.js (component)
import React, { Component, PropTypes, DOM, createElement as $ } from "react";
class Html extends Component
{
static propTypes =
{
title: PropTypes.string,
description: PropTypes.string
};
static defaultProps =
{
title: "",
description: ""
};
render()
{
const { title, description, children } = this.props;
return (
DOM.html({},
DOM.head({},
DOM.meta({charSet: "utf-8"}),
DOM.meta({httpEquiv: "X-UA-Compatible", content: "IE=edge"}),
DOM.meta({name: "description", content: description}),
DOM.meta({name: "viewport", content: "width=device-width, initial-scale=1"}),
DOM.link({rel: "stylesheet", href: "/app.css", type: "text/css"}),
DOM.title({}, title)
),
DOM.body({},
DOM.div({id: "app"}, children),
DOM.script({src: "/app.js"})
)
)
)
}
}
export default Html;
In theory, you are setting up simple express server and using ServerDOM which is react js server side rendering to render the Html component.
Then you including file like app.js which could be a bundle compiled using something like webpack (only if you want, I'll extremely recommend it) then you simply put it on the Html component and you done.