toString() of Undefined in Universally Rendered(React&Express&AltJS) through Webpack - reactjs

I have a strange issue and I'm not sure what part of my stack is responsible for throwing the error. I currently have an es6/webpack/react-router rc2/flux(altjs) isomorphically(universally) rendered application. If there are any bugs on any part of the frontend(syntax error or otherwise) or an api endpoint is incorrect/not responding the appropriate data format(i.e. an array isn't being sent back which therefore cannot be mapped over by one of my react components) the server crashes with the following error
Cannot read property statuscode.toString() of undefined
Is this react-router related? Webpack related? React related? I wish I could have a more informative stack trace because as I work through the backend as I'm not sure what is incorrect, whether it is front-end code or backend code. Is there any way to "catch" what is occurring. To clarify nothing else changes but the expected data structure which throws this error.
Edit:
export default class Dashboard extends React.Component {
constructor(props) {
super(props);
this.state = {
data: DataStore.getState().data
};
}
render() {
return (
<div className='dashboard'>
<Tile gridWidth='cute-6-laptop' linkTo='/data/temperature/water' size='regularTile' title='Water Temperature'>
<OverviewChart data={this.state.data.Water_Demand.devices} mapObj={mapObjs.water} keyData={[{key: null, value: this.state.data.Water_Demand.devices[2].readings[this.state.data.Water_Demand.devices[2].readings.length - 1].rate, units: this.state.data.Water_Demand.devices[2].rateUnits}]} chartClass='interiorTemperature' includeNavChart={false} includeBarChart={false} w='473' h='180'/>
</Tile>
</div>
);
}
}

Related

How to solve hydration errors related to dates in a React / Remix application?

I'm building an application as a hobby project and as an effort to try and learn server rendered React, but I've stumbled on a seemingly easy to fix error, but I do not know how I should approach the problem. Using Remix 1.10.
While my code runs, it is flawed. The server renders one thing and the client another, causing the rendered element to flicker on pageload. It also throws a multitude of errors in the console, like:
Uncaught Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
24x react-dom.development.js:12507 Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
react_devtools_backend.js:4012 Warning: Text content did not match. Server: "1/29/2023, 10:44:09 AM" Client: "1/29/2023, 12:44:09 PM"
The server is on UTC timezone but the client can be anything. In this case it's GMT+2. What should I do? I think I could set the server timezone to what the client timezone is but I also think that might be a terrible idea.
The best barebones dumbed down example I could make is this.
// routes/example.tsx
import { useLoaderData } from "#remix-run/react"
import {json, LoaderArgs } from "#remix-run/server-runtime"
export async function loader({ request }: LoaderArgs) {
const timestampFromDB = "2023-01-29T10:44:09.672Z"
return json({ time: timestampFromDB })
}
export default function HydrationError() {
const loaderData = useLoaderData<typeof loader>()
const time = new Date(loaderData.time)
const stamp = time.toLocaleString("en-US")
return (
<div>
Time:
<time>{stamp}</time>
</div>
)
}
I tried to look for answers before asking, but the closest thing I found isn't even close to what my problem is; Remix Hydration failed: UI on server and client do not match. In my case, it's not fine locally, it's not fine at all.
The toLocaleString spec allows output variations across implementations so you're probably better off avoiding the client's implementation and just using the server's implementation by moving toLocaleString to the loader.
// routes/example.tsx
import { useLoaderData } from "#remix-run/react"
import {json, LoaderArgs } from "#remix-run/server-runtime"
export async function loader({ request }: LoaderArgs) {
const timestampFromDB = "2023-01-29T10:44:09.672Z"
return json({ stamp: new Date(timestampFromDB).toLocaleString('en-US') })
}
export default function HydrationError() {
const { stamp } = useLoaderData<typeof loader>()
return (
<div>
Time:
<time>{stamp}</time>
</div>
)
}
Alternatively you might want to look at Intl.DateTimeFormat which gives you greater control over date rendering and may offer more consistency.
React Intl is a library built on top of Intl.DateTimeFormat which is worth checking out.

visual studio react image path cannot reach

So i have a visual studio project created with react.js.
I am trying to link to an image dynamically, but failing. This is the code I am trying:
At the top im setting a variable for the first part of the path:
this.LogoPath = '../images/'
And then im dynamically grabbing the name of the image from an api call.
this.setState({ imageNamePath: this.state.location.imageName })
And then im concatinating them:
{`${this.LogoPath}${this.state.location.imageName}`}
In the console, im getting:
img src='../images/the-images-name-here.png'
So it seems to be working, but it is not. I get no errors, and I have broken images. My best guess is that react is changing the images to something like:
image-name-here.6a131799.png
Surely someone has run across this before, but my google search pulled up little help.
So how do i get the images to show?
Webpack is a smart tool. One of it's strength is the trash code/files elimination from the bundle.
That means that if a file is not imported using import myFile from '../myPath/myFile.jpg'; or require('../myPath/myFile.jpg');` it won't be a part of the final bundle.
In your case you're not importing the file. You're creating a string variable instead which means nothing to webpack.
There are different options that could work in your case:
Option 1: Pre-import all images and map them in an object:
import React, {Component} from 'react';
import image1 from '../assets/image1.png';
import image2 from '../assets/image2.png';
import image3 from '../assets/image3.png';
const imageTypes = {
image1,
image2,
image3,
}
export default class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
imageType: 'image1'
}
}
render() {
return (
<img src={imageTypes[this.state.imageType]} />
)
}
}
Option 2: Not recommended - Use require to dynamically import files (webpack configurations might be needed in order to include all possible required images in the production bundle):
class MyComponent {
constructor(props) {
super(props);
this.state = {
image: 'file1.png'
}
}
render() {
return (
<img src={require(`./assets/${this.state.image}`)} />
)
}
}
Option 3: Send the image blob (in base64) from the API.
I suggest you to use the Option 1 or Option 3, based on your requirements, such as: how often will be images be changed/added/removed. It's not normal to import files dynamically from ReactJS bundle and you might end up having a non-existing image in your project requested by the data coming from an external source.
For Option 2 you also might have some problems configuring the webpack in order to include in the bundle all the images that you'll probably need to render, even though they are not imported (hardcoded) somewhere in the JS files. Keep in mind that the React Application in production ends up being a collection of static files. You'll need to treat them as follows.

Fetch As Google Is Showing Blank Page - Reactjs

I have a Reactjs (v.16.6.3) page which its SEO is important to be indexed by Google. Therefore, I checked it with Fetch as Google tool to know what Google-bot renders from this page.
However, google shows nothing and only depicts a blank page to me!
I have added 'babel-polyfill' to fulfill es6-es7-es8 requirement and make google-bot happy since I have used async-await (es8) approach in ComponentDidMount (to load async data in this lifecycle method) and other methods. Also popular arrow functions have been used though and result is nothing in Fetch as Google again!
I even get no result while importing some flat data (like the following I have written) which are only imported from another module and put directly to render method (not in componentDidMount). I have checked and found that they exist to main.chunk.js and Google should read and render them adequately but nothing happened!
export const sampleData01= [
{name: sampleName01,
lastName: sampleLastName01,
image: sampleImage01
},
{name: sampleName02,
lastName: sampleLastName02,
image: sampleImage02
}
]
export const anotherData02= [
{name: anotherName01,
lastName: anotherLastName01,
image: anotherImage01
},
{name: anotherName02,
lastName: anotherLastName02,
image: anotherImage02
}
]
-----------
import React, {Component} from 'react'
import {sampleData01} from './tempData'
import Helmet from "react-helmet";
class SampleClass extends Component {
state = {...something , loading:false}
async componentDidMount = ()=> {
this.setState({loading:true})
...await fetch something
this.setState({loading:false})
}
}
render(){
const data = sampleData01.map(item => {
<li>
{item.name}
</li>
}
return (
<div className="...">
<Loading loading={this.state.loading}/>
<div className="...">
<Helmet link={....} title={....} meta={....} />
<ul>
{data}
</ul>
</div>
</div>
)
}
export default SampleClass
eveything is working fine on both dev and production mode. I have checked every possible ways such as importimg es6-shim, isomorphic-fetch, url-search-params-polyfill, whatwg-fetch and got no result! I have read in some article that google might use phantomjs for rendering page. I have checked out page with phantomjs by myself in the web (not local) and it shows and renders perfectly fine. I have read lots of articles say there is no issue with Google search and SPAs while I am seeing something else! It seems I should shift to SSR for more convenient way to ensure having SEO friendly page.
I have tried so many dirty hacks to improve SEO for Client Side rendering website but in the end SSR was the only option. Either make your own SSR project using or using Razzle (https://github.com/jaredpalmer/razzle) or Next.js (https://github.com/zeit/next.js/)

firebase serve - React Context returns undefined

I'm currently facing a problem with a firebase deployment, happening only in production environment. I cannot reproduce it in local, with the firebase serve command; even if I'm using the target 6.11.5 node version.
Here is my trouble : when deployed, the site will crash (server-side) rendering a React component using a Context's return property
Component extract :
<div className='rank-item col-sm-6 col-lg-3'>
<LangContext.Consumer>
{
({ lang, langs }) => (
// here, props are cools in development
// but are undefined in production
)
}
</LangContext.Consumer>
</div>
App root component (at this point, props.lang & props.langs are correctly set, even on production environment) :
export default props => (
<LangContext.Provider value={ {
lang: props.lang,
langs: props.langs
} }>
</LangContext.Provider>
)
The problem as shown in the console :
As you may have guess, I'm building my SSR code with webpack to commonjs2 module. The error stack trace here refers to this exact line of built code :
I'm a bit surprised because I already used React's Context feature on a production environment, but cannot figure now what could be the problem. Thanks for your help

Error thrown when react component refreshes

I have a react typescript component that has the following componentDidMount method:
componentDidMount() {
ComponentFields.get(this.ComponentName)
.then(activeFields => {
this.setState({ activeFields });
});
}
It has a state interface with following field
export interface ISettingsPageState {
activeFields: Dictionary<IComponentField>,
}
where IComponentField is an interface.ComponentFields.get(componentName: string) is a static method which returns a Promise<IDictionary<IComponentField>>.
It works fine the first time it loads but when I refresh the page, the setState method in componentDidMount throws the following exception:
Uncaught DOMException: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
Anyone have any idea what could be causing this?
It turns out that it was a child component throwing the error. Even though the exception was being thrown at the setState line, the problem was in my rendermethod. If anyone has the same problem, I would suggest taking a look at the render method to see what's going wrong.

Resources