post-robot in React - cannot read properties of undefined (send) - javascript

I have installed the post-robot package to my react project.
My project works as a web app which is embedded into a Web Client application and displayed using an IFrame. I know this web client uses post-robot library to handle communication events and I also know it is has an EventListening set on "loading".
Like any other packages, I have imported post robot in my main app component
import { postRobot } from 'post-robot'
I tried to send the corresponding message the webclient is expecting :
const sendMessage = (message, success) => {
//parent window is the holding web client, message is "loading", success is false
postRobot.send(window.parent, message, success)
however, when this function is called in the hook at runtime, an error occurs saying that React does not recognize '.send()' as a valid method.
Uncaught TypeError: Cannot read properties of undefined (reading 'send')
at sendMessage (App.js:32:1)
at App (App.js:60:1)
I am puzzled. React seems to not recognize post-robot package, however, VS does not preventively throw any warning/errors (like it usually does) which would mean the package has been installed successfully. Am I doing this wrong or is post-robot not meant to be used on a React project ?
I tried to answer the EventListener (i.e. postRobot.on()) on the WebClient side which is holding my React Web AP through an IFrame. This listener event should be answered to notify the Web Client side that my React App is ready. If not, a loading overlay is covering the full page. My app is visible in the background but not accessible because of this overlay.

Related

Nuxt.js Facebook Login appending '#_=_' to uri

I see plenty of others have had issues with facebook appending this to the callback uri and saw some good solutions for handling this client side with js embedded in the page. I have a nodejs api that handles the actual authorization with passportjs and passes it to our frontend (nuxtjs based on vue 2). The client stalls when trying to access/redirect any routes after being sent to the uri with the appended
I was hoping I could fix it with
//dashboard.vue
mount(){
if (window.location.hash == "#_=_"){
window.location.hash = ''
}
}
but this doesn't seem to fix anything with the router. I also tried adding a redirect to the vue router
//.nuxt/router.js
{ path: "/dashboard#_=_", redirect: "/dashboard" }
but the vue router dynamically generates on runtime so anything I hard-code there gets undone.
From what I undestand this is strictly a client side problem, but maybe I'm missing some parameter in the Facebook API call that could prevent this?
//backend api calling fb api
app.get('/facebook', passport.authenticate('facebook')) //not specifying scope since still in dev and haven't applied for approval

MetaMask does not inject window.ethereum: Uncaught (in promise) TypeError: Cannot read property 'request' of undefined

To start, let me mention this is an in-browser project, so i can only use
<script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js"></script>
So a few months back I made a dapp, which worked fine even tho I never set a provider, so I guessed it used the ones given by MetaMask.
However, i am using the guide here the only issue is the following code,
var account_global, connected = false;
async function connect() {
if (!connected) {
var wei;
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' }); // Waits for connection to MetaMask.
account_global = accounts[0];
web3.eth.defaultAccount = account_global;
console.log(account_global.toString() + " connected!");
connected = true;
console.log(account_global);
}
}
connect();
This code used to output the address of the metamask user after they approved metamask on my dapp, however I am receiving the error
Uncaught (in promise) TypeError: Cannot read property 'request' of undefined
The error just says that, my actual goal if i have to add providers and all is to use the ones from metamask, and allow connecting to metamask, the rest of the functions such as transfer or others i know how to handle them, it just seems that my issues come when i try loading the page.
I dont have an ether node to use, not planning on using nodejs either, only a single html file displaying the Metamask address, hence using the in-browser web3js.
I hope its just me not realizing something simple, because I cant seem to find the reason I cannot use web3js right now.
The actual problem is, that you need to run your script on some server. For testing purposes you can use localhost.
Please, refer to this link on how to start local server. And just open your file via localhost:XXXX where XXXX - are the port number.
Solved the mystery, seems to be just like the error code showed
Uncaught (in promise) TypeError: Cannot read property 'request' of undefined
genuinely meant that window.ethereum was undefined, so for no exact reason MetaMask would not inject ethereum, noticed that after reading Metamask and Web3js documentation, that my issue had nothing to do with their code, in fact i am gonna end up using the code shown on this answer.
https://ethereum.stackexchange.com/a/78987
The issues seeems that no matter the browser Metamask would not inject, so i tested it on multiple websites that usually require Metamask to connect and other normal sites just as google.com, to my surprise every site would have Metamask injecting ethereum apart from my own test site, so it meant that my site was cursed or something, or just the fact that Metamask does not inject on unhosted websites (just had the files on my destop to test), instead on an actual host it did inject and my tests were working on those sites.
Conclusion
Metamask requires a normal host to inject, it wont inject on a random file opened on your own workstation.
I had the exact same issue and it turned out my HTML was a bit dodgy (had an extra tag before the <html> tag) and that was preventing MetaMask from injecting web3.

Avoiding Net.createConnection errors in Node

I am currently building an app with React and Node.js
In this app, I need to query a database on my own server with the following function, located in a separate file called "database.js"
const fetchQuery = util.promisify(con.query).bind(con)
// Get all the tracks for a given date from the
const fetchTracks = async (date) => {
const rows = await fetchQuery("SELECT * FROM tracks WHERE playlistDate = '"+date+"'");
}
This works perfectly when I run the file with Node from the command line. However, when I attempt to import it into my react app with
import { fetchTracks, addTracks } from '../scripts/database'
I begin to get errors in the database file, specifically Unhandled Rejection (TypeError): Net.createConnection is not a function on my fetchQuery call.
From what I've read, this happens when attempting to call the function from the browser, as that would pose a security risk. However, as I understand it, all node operations are performed on the server side, right? Why would I be getting this flag when the database is supposedly queried before the page is served? What do I need to do amend this?
React runs in the browser, so as soon as you include database.js in your React app, it's running in the browser with the rest of React, so of course you'll get the error. Making this work gives two options:
expose an API endpoint from Node for React to call, and that API endpoint calls database.js, or,
investigate server-side rendering for React, where some of your React app -- particular the more static parts of it like your main menu -- are created on the Node side and only the final HTML is sent to the browser. (This is a large topic all by itself though.)
By your example which takes a date parameter for the SQL, I'm guessing #2 isn't an option.

Web Scraping With Puppeteer In React JS [duplicate]

This question already has an answer here:
How to make Puppeteer work with a ReactJS application on the client-side
(1 answer)
Closed 2 years ago.
I am trying to use the web scraper from https://github.com/BlakeStevenson/populartimes.js in my React JS project for school.
I keep getting an error that says:
../node_modules/populartimes.js/node_modules/puppeteer/lib/WebSocketTransport.js
Module not found: Can't resolve 'ws' in ...
I did some research and I believe its an issue with how puppeteer interacts with React JS. Is there anyway I can fix this?
This is all the code that I am using that is associated with the scraper:
import React, { Component } from 'react';
import { Map, GoogleApiWrapper, InfoWindow, Marker } from 'google-maps-react';
let temp;
const populartimes = require('populartimes.js');
populartimes('ChIJKznozuF0hlQRbfbe7fJJ1rM').then(out => {temp=out.now.percent});
I have installed both websocket and puppeteer.
The problem is that you are trying to use populartimes.js/puppeteer in your React.Js app (on the client/frontend side) which is not possible at the moment. Unpackaged versions of puppeteer neither won't work even if you've added them in your HTML source.
You need to use populartimes.js/puppeteer on the server (backend) side. So if your app is React.Js-only so far: you will need a Node.Js server as well to run the scrapers and to make their output data available to your React.Js app via an endpoint (most probably you would choose Express for this purpose).
Edit: To get some ideas about the relationship between the Node.Js backend, Express and React.Js client app I can recommend this tutorial on dev.to.

socket.io is not working correctly with React js Node.js and Express.js

I am trying to integrate the socket.io with React.js I am running socket.io on server with Express.js back end.
The problem is this I am on homepage and when order is placed from homepage then i am showing that order in the Orders page of React but the problem is it sometimes shows the order but it sometimes does not shows the order and if i open multiple tabs on different browsers then on some tabs in some browsers the order does not show mean the socket connection does not work some time but in all of the cases when ever a order is created from home page then the emit from the socket.io from home page is showing in the Node.js Express.js back end.
Please note I am using clustering module on the express.js
Here is how i am creating the socket.io connection.
socket = io('http://localhost:5000',{ reconnect: true ,transports: ['websocket']});
Here is my homepage react component from where i am placing the order.
socket.emit("putKitchenOrder", Order);
Here is my second component on which i want to show the order which is placed in real time using socket.io
componentWillUnmount(){
socket.off("kitchen-channel:orderPlacedFromPos");
}
componentDidMount() {
socket.on("kitchen-channel:orderPlacedFromPos", (order) => {
console.log('order in orderPlacedFromPos');
console.log(order);
alert('order in orderPlacedFromPos')
});
}
Here is my Node.js and Express.js code
io.on("connection", socket => {
socket.on("putKitchenOrder", order => {
// this console.log is always showing in the node.js console window when ever a new order is placed from the homepage component but the second page is not getting the following emit "kitchen-channel:orderPlacedFromPos" sometime.
console.log('putKitchenOrder order');
io.emit("kitchen-channel:orderPlacedFromPos",order);
});
});
The console.log('putKitchenOrder order'); is always showing in the node.js console window when ever a new order is placed from the homepage component but the second page is not getting the following emit "kitchen-channel:orderPlacedFromPos" sometime.
From what I know when you switch between components the components are mounted again. So maybe you can create a singleton for the socket instance like in this article, and put a log in the file where you create the socket, you can debug with that and also can be the solution

Categories