react prop passing to child component only works with localhost backend - node.js

I'm kinda losing my mind as I have no idea what is the problem or how to approach it.
I have the same files in in my backend server (hosted on heroku) and local directory and the same goes for the frontend
const SOCKET_SERVER_URL = 'https://backendserverurl.com';
// const SOCKET_SERVER_URL = 'http://localhost:5000';
I'm trying to set the useState by listening to a socket event listener
(both local backend server and heroku server receives the data from socket listener "currentRoom")
const [myRoom, setMyRoom] = useState(null)
...
...
...
socket.on("currentRoom", (args) => {
setMyRoom(args)
console.log("logging inside lobby ")
console.log(args)
});
and pass it to a child component under return.
return (
...
<Game socket={socket} setInLobby={setInLobby} roomPlayers={roomPlayers} room={myRoom} />
...
)
Inside the child component: "Game" is able to receive the room prop when I'm using localhost as the backend but no data is passed on when I'm using the hosted backend as the SOCKET_SERVER_URL.
const Game = ({ socket = null, setInLobby = null, roomPlayers = null, room = null }) => {
...
...
// logs the room if the backend is localhost but is null when backend is hosted online
console.log(room)
...
...
)}
I'd understand if there's a problem with the frontend but I'm not sure why the useState variable is not able to be passed as a prop if the backend is not local hosted.
Please let me know if you require more information. Thank you

return (
...
{(!inLobby && myRoom) &&
<Game socket={socket} setInLobby={setInLobby} roomPlayers={roomPlayers} room={myRoom} />
}
...
)
Oops, it turns out the delay added when the hosted backend is used is too slow for the data to be fetched to the frontend.
Adding
{(!inLobby && myRoom) &&
...
}
To wait for the data to be received fixed the problem

Related

Query parameters not received from deep linking - react native(expo) and node js

I am using openAuthSessionAsync to do a call to my backend and sending the url for deep linking
I am redirected back successfully to my app but i don't get query parameters that i send from backend with deep link
My react native app side:
const experiment = async()=>{
try{
let result = await WebBrowser.openAuthSessionAsync(`http://myaddress :3901/api/testig?linkingUri=${Linking.createURL(
"/?",
)}`,);
console.log(result)
}catch(errr){
console.log(errr)
}
}
My node js side:
router.get("/testig",(req,res)=>{
url = req.query.linkingUri
**//url is exp://myaddress:19000/--/?**
res.redirect(url+"?authToken=abc123")
})
I have also tried hard coding the url in backend but it only opens app back but with no parameters
And in my react native side in console i get this:
Object:{
"type":"dismiss",
}
UPDATE: Solved it by setting up eventListener for LINKING as follows
const handleDeepLink = (event)=>{
let data = Linking.parse(event.url)
setdata(data)
if(JSON.parse(data.queryParams.isSuccessful) == true)
{
props.navigation.navigate("thankyou")
}
}
React.useEffect(()=>{
Linking.addEventListener("url",handleDeepLink)
return(()=>{
Linking.removeEventListener("url")
})
},[])
use trycarch in the block to see errors and use var url
code lookslike
router.get("/testig",(req,res)=>{
try {
var url = req.query.linkingUri
return res.redirect(url+"?authToken=abc123")
} catch (e) {
console.log(e)
}
})

Data goes null after few successful requests - Node service App pool caching

I have a service built using Node and Express and MongoDB as database. Service is hosted on IIS.
There is a side filter panel section in the application. Since that filters' master information does not change often (Data Size is in KBs), I use basic Node caching technique(no npm package) to avoid going to database on each page load request. Below is the sample Node code:
//main index.js file
SetFiltersList() function is called as Node service is first initialized on IIS, or, when app pool recycles.
(async () => {
await init.SetFiltersList();
})();
//init.js (utility file)
let filtersList = null; // filterList object that keeps list of Filters as cached object
const SetFiltersList = async (_error) => {
//This is a MongoDB database call
result = await defaultState.DEFAULT_STATE.GET("FiltersList");
filtersList = result.filters;
}
//Get filters call
const getFiltersList = () => filtersList;
module.exports = {
FiltersList: getFiltersList
};
//Controller.js
const GETFILTERLIST = async (req, res, next) => {
res.send(init.FiltersList());
}
//Controller Route
approuter.route('/GetFilterList/')
.get(Controller.GETFILTERLIST);
Problem
After few calls, Filters start returning null and strangely when I recycle the Application pool, the Filters starts coming again for sometime and this repeats after period of time.
Any thoughts whats going wrong here and how I can overcome this?

How can I import an image from the express server to the client (in React)

I'm trying to show an image in react, which is neither a local image (in the client) nor an external image from the web but an image that is in the node.js express server (and I don't want to call it as if it was an external image, because the domain could change and it just doesn't seem right).
I know I can't just import it like I do with a local image in the client because we're speaking about different localhosts. I did try this:
loadImage = async (imageUrl) => {
const response = await fetch(`/api/images/${imageUrl}`);
const data = await response.json();
this.setState({ image: data });
}
componentDidMount() {
const { imageUrl } = this.props;
try {
this.loadImage(imageUrl);
} catch(error) {
console.log("Hay un error: " + error);
}
}
render() {
const { image } = this.state;
return(
<div>
<div>
<img alt="dontknowyet" className="blog-list-image" src={image} // and so on...
{image} does receive the correct path, but the image won't load and the console throws this error:
Not allowed to load local resource: file:///C:/Users/Dafna/Desktop/adrian/proyectos/esteticand/img/t4.jpg
So how can I make it work? and in case that I need to import the image file instead of just the link, how can I do that? (I can't update the state with an image...)
In order to access the path of the image it has to be done through the express server.
For example, if the (backend) server is running on port 4500 and the image is in a folder called images, and the express variable is called app, in the server file you have to use:
app.use(express.static('images'));
and then the image can be accessed in http://localhost:4500/nameoftheimage.jpg.
Do you have the api running on the same port as the React app?
You usually would make them run on different ports. Maybe it's got something to do with it.

Angular how to show live value of json object

In angular , I am trying to display one json object to client html. Using below route on server side.
const express = require('express');
const jsonRoute = express.Router();
jsonRoute .route('/json').get(function (req, res) {
var JsonObj = { rank: 73 } ;
res.end(JSON.stringify(JsonObj));
});
setInterval(function(){
JsonObj.rank = parseInt(Math.random()*100);
}, 1000); // this interval may be anything.from ms to minutes.
module.exports = jsonRoute ;
this works on http://localhost:4000/json and displays ,
{"rank":73}
But does not show the values changed in setInterval. And same route i am using in a angular service (using http).
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class getjsonService {
uri = "http://localhost:4000/json";
constructor(private http: HttpClient) { }
jsondata(){
return this.http.get(`${this.uri}`);
}
}
This value i am displaying in component html page. The problem is, it is not showing updated value of json. Please suggest how can i show live json value in angular. Please note, in realtime my json object going to be big in size , around 100 keys and value and i want to show live value for all key. And also change value interval may not be fix as one second. it may be in milliseconds as well.
Thanks
By default http will not persistent the connection. It's http protocol limitation not from angular.If you want to show the value in real time, you need to use web sockets.
There are lot of library out there will help with real time data connection. https://socket.io/ is very popular. check this out
Tutorial :https://alligator.io/angular/socket-io/
Your problem is a structural one with how RESTful architecture works. Your server only sends the new data to your angluar app when your app asks for it, not when your server detects a change. What you will need to do is either add a set timeout in your angular project that will call the server for the new data every few seconds.
setInterval(function(){ var JsonData = getJsonService.jsondata() }, 3000);
console.log(JsonData);
//This will refetch the data every 3 seconds you can lower this number to make it refresh more often
The other option is to rewrite your server to use web-sockets as Ravin pointed out.
In your node.js code, you are re-inializing the JsonObj variable every time the request is made. You should store the value as a global variable:
const express = require('express');
const jsonRoute = express.Router();
var JsonObj = { rank: 73 };
jsonRoute .route('/json').get(function (req, res) {
res.json(JsonObj);
});
setInterval(function(){
JsonObj.rank = parseInt(Math.random()*100);
}, 1000); // this interval may be anything.from ms to minutes.
module.exports = jsonRoute ;

Using react-hot-loader 3 with own server

I was able to set up react-hot-loader to work properly bundling my client js and pushing changes to browser and applying there (except [react-router] You cannot change <Router routes>; it will be ignored warning).
I'm using my own server with koa, koa-webpack-dev-middleware and koa-webpack-hot-middleware, that processes webpack and hot. It also handles server rendering of my app with this code
export default function *renderReact() {
const history = createMemoryHistory();
const store = makeStore(history);
const [redirectLocation, renderProps] = yield match.bind(null, { routes, location: this.url, history });
if (redirectLocation) {
return this.redirect(redirectLocation.pathname + redirectLocation.search)
}
if (renderProps == null) {
return this.throw(404, 'Not found')
}
const rootElement = (
<Provider store={store} key="provider">
<RouterContext {...renderProps} />
</Provider>
);
this.body = renderApp({
html: yield store.renderToString(ReactDOMServer, rootElement),
state: JSON.stringify(store.getState())
});
}
The problem is with my server side code: hot works only for client code and updates changes on the fly, but my server code does not get updated on changes as scripts a loaded on server start and on page reload i get not updated rendered page from server and then it updates with new client code.
and react warning Warning: React attempted to reuse markup in a container but the checksum was invalid...
The question is: how to handle code changes related to server rendering part on server not restarting the app as it breaks hot loading?

Resources