Invariant Violation: React error #130 - node.js

So i was currently trying to render the code for a custom sidebar found in the site: How to build a custom sidebar in React
. But i am getting the error:
Element type is invalid: expected a string (for built-in components)
or a class/function (for composite components) but got: undefined.
Check the render method of TheSidebar
I cannot comprehend what is wrong with it, but still, i am new to React. Running it on Node. Any help is appreciated.
Here is the code:
const React = require('react');
const ReactDOM = require('react-dom');
const { IndexLink, Link } = require('react-router');
// import './Sidebar.scss'
const classNames = require('classnames');
class TheSidebar extends React.Component {
constructor(props) {
super(props);
this.state = {
showMenu: false
}
this.toggleMenu = this.toggleMenu.bind(this)
}
componentDidMount() {
document.addEventListener('click', this.handleClickOutside.bind(this), true);
}
componentWillUnmount() {
document.removeEventListener('click', this.handleClickOutside.bind(this), true);
}
toggleMenu() {
this.setState({ showMenu: !this.state.showMenu })
}
handleClickOutside(event) {
const domNode = ReactDOM.findDOMNode(this);
if ((!domNode || !domNode.contains(event.target))) {
this.setState({
showMenu: false
});
}
}
render() {
const showMenu = this.state.showMenu;
const sidebarClass = classNames({
'sidebar': true,
'sidebar-menu-expanded': showMenu,
'sidebar-menu-collapsed': !showMenu
});
const elementsClass = classNames({
'expanded-element': true,
'is-hidden': !showMenu,
});
return (
<nav className={sidebarClass}>
<img
className="menuIcon"
// src={}
onClick={this.toggleMenu}
/>
<ul>
<li>
<Link className="expandable" to="/setting" title="Setting">
<img
src={'https://png.icons8.com/setting/ffffff'}
alt=""
/>
<span className={elementsClass}>Setting</span>
</Link>
</li>
</ul>
</nav>
);
}
}
module.exports = TheSidebar;
The sidebar is then injected into an App file along with a header and then rendered. The app file and render file are as follows:
const React = require('react');
const Header = require('./Header.jsx');
const TheSidebar = require('./Sidebar.jsx');
class App extends React.Component {
render() {
return(
<div>
<head>
<title>TESTING</title>
</head>
<body>
<div>
<Header />
</div>
<div>
<TheSidebar />
</div>
</body>
</div>
);
}
}
module.exports = App;
And the rendering:
app.set('views', path.join(__dirname, "../views"));
app.set('view engine', 'jsx');
app.engine('jsx', createEngine());
app.get("/testing", function(req, res){
res.render('pages/App.jsx');
});

Link and IndexLink are exported as fields within a default object export, so if you're using "require" then first get the default export:
const ReactRouter = require('react-router')
And then pick out individual fields:
const IndexLink = ReactRouter.IndexLink
const Link = ReactRouter.Link
EDIT: If your react-router version is >= 4.0, then Index is longer inside it. Its in react-router-dom. And IndexLink is no longer available. You should probably revert to 3.x to run this example code

You are not importing the IndexLink and Link component correctly. Check out named imports in ES6.
You should import them like this.
import { IndexLink, Link } from 'react-router'

Related

how to solve this no-unused-vars error in NodeJS?

I am creating a todo app using MERN stack.I am new to MERN stack technology and I kindly neeed your help solving this error.I have provided the code for my app.js file and todo.js file.I can't clearly find the solution of this error anywhere on the internet.
I am getting this error while runnng the node js app using npm start command.
Compiled with warnings.
src\App.js
Line 4:8: 'Todo' is defined but never used no-unused-vars
Search for the keywords to learn more about each warning.
To ignore, add // eslint-disable-next-line to the line before.
App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';
import Todo from './components/Todo.js';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;
Todo.js
import React, { Component } from 'react'
import axios from 'axios';
// eslint-disable-next-line
export class Todo extends Component {
constructor(props) {
super(props)
this.state = {
todos : [],
item : ""
}
}
changeHandler = (event) => {
this.setState({item: event.target.value})
}
clickHandler = (event) => {
event.preventDefault()
console.log(this.state.item)
axios({
method: 'post',
url: 'http://localhost:3000/',
data: {
todo: this.state.item,
}
});
this.setState({item:''})
}
componentDidMount() {
axios.get('http://localhost:3000/').then((response) => {
console.log(response.data.data)
let data = [];
console.log(response.data.data.length)
for(var i =0; i < response.data.data.length; i++){
data.push(response.data.data[i].todo)
}
this.setState({todos: data})
});
}
componentDidUpdate() {
axios.get('http://localhost:3000/').then((response) => {
console.log(response.data.data)
let data = [];
console.log(response.data.data.length)
for(var i =0; i < response.data.data.length; i++){
data.push(response.data.data[i].todo)
}
this.setState({todos: data})
});
}
render() {
return (
<div>
<input type="text" onChange={this.changeHandler}/>
<button type="submit" onClick={this.clickHandler}>add</button>
<div>
<ul>{this.state.todos.map((todo, index) => <li key={index}>{todo}</li>)}</ul>
</div>
</div>
)
}
}
export default Todo
That warning you are getting because even though you are importing Todo file in your App.js file but you aren't using it anywhere.Either try using it in App.js or remove the import(in case you don't need it).That should fix the warning.
Or add // eslint-disable-next-line just before the import Todo.. statement in App.js

Only one element of type cardNumber can be created

I am trying to display my stripe component, but I am getting this error:
IntegrationError: Only one element of type cardNumber can be created.
I don't know why, since I'm only using it once in my entire app
Any ideas?
This is my index
import ReactDOM from 'react-dom';
import App from './App';
import * as serviceWorker from './serviceWorker';
import { loadStripe } from "#stripe/stripe-js";
import { Elements } from "#stripe/react-stripe-js";
import MyComponent from './components/StripeComponent';
const promise = loadStripe("xxx-xxx-xxx");
ReactDOM.render(
<React.StrictMode>
<Elements stripe={promise}>
<MyComponent/>
</Elements>
</React.StrictMode>,
document.getElementById('root')
);
And this is my component
import React from "react";
import {
useElements,
} from "#stripe/react-stripe-js";
const MyComponent: React.FC= (props)=>{
const elements = useElements();
const cardNumberElement = elements?.create('cardNumber', {
placeholder: ''
});
const cardExpiryElement = elements?.create('cardExpiry', {
placeholder: ''
});
const cardCvvElement = elements?.create('cardCvc', {
placeholder: ''
});
cardNumberElement?.mount('#card-number-element')
cardExpiryElement?.mount('#card-expiry-element')
cardCvvElement?.mount('#card-cvv-element')
const handleSubmit = async (ev: any) => {
ev.preventDefault();
};
return (
<form id="payment-form" onSubmit={handleSubmit}>
<div id="card-number-element"></div>
<div id="card-expiry-element"></div>
<div id="card-cvv-element"></div>
</form>
);
}
export default MyComponent
Seems it is because you create and mount the card components in the functional component body they are executed on every render of the component, i.e. as an inadvertent side-effect.
Place the creation and mounting logic in an useEffect hook with an empty dependency array so that it is invoked only once when the component mounts.
import React, { useEffect } from "react";
import { useElements } from "#stripe/react-stripe-js";
const MyComponent: React.FC = (props) => {
const elements = useElements();
// Effect hook to run once on component mount
useEffect(() => {
const cardNumberElement = elements?.create("cardNumber", {
placeholder: ""
});
const cardExpiryElement = elements?.create("cardExpiry", {
placeholder: ""
});
const cardCvvElement = elements?.create("cardCvc", {
placeholder: ""
});
cardNumberElement?.mount("#card-number-element");
cardExpiryElement?.mount("#card-expiry-element");
cardCvvElement?.mount("#card-cvv-element");
}, []); // <-- empty dependency array
const handleSubmit = async (ev: any) => {
ev.preventDefault();
};
return (
<form id="payment-form" onSubmit={handleSubmit}>
<div id="card-number-element"></div>
<div id="card-expiry-element"></div>
<div id="card-cvv-element"></div>
</form>
);
};
useEffect(() => {
if (elements) {
const cardNumberElement =
elements.getElement("cardNumber") || // check if we already created element
elements.create("cardNumber", defaultInputStyles); // create if dont
cardNumberElement.mount("#numberInput");
}
}, [elements]);
I had the same problem, in my case, I had a reference to CardNumberElement in another section of my code. After removing it, everything worked fine.

Error Getting Data from API using FetchData

i am using a react hook : useEffect for getting data from an API and i'm also using .map for rendering an array of product.
after run the npm , there is an error :
xhr.js:178 GET http://localhost:3000/api/products 404 (Not Found)
import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import axios from 'axios'
function HomeScreen (props) {
// menggunakan hooks
const [products, setProduct] = useState([]);
// fetchDate from server // sama dengan component did mount
useEffect( () =>{
const fetchData = async () => {
const { data } = await axios.get("/api/products");
setProduct(data)
}
return () => {
fetchData();
}
}, [])
return(
<div>
<ul className="products">
{
products.map( product =>
<li key={product.id}>
<div className="product" >
<Link to = {`/product/${ product.id }`}>
<img className='product-image' src={ product.image } alt={product.name} />
</Link>
<div className="product-name">
<Link to = {`/product/${ product.id }`}>{ product.name }</Link>
</div>
<div className="product-cat">{ product.brand }</div>
<div className="product-price"><b>IDR</b> { product.price }</div>
<div className="product-rating">{ product.rating } Stars ( { product.reviews } Reviews )</div>
</div>
</li>
)
}
</ul>
</div>
)
}
export default HomeScreen
and there is code from server.js
const express = require('express');
const data = require('./database/data')
const app = express();
app.get('/api/products', ( req, res) => {
res.send(data.Products)
})
const PORT = process.env.PORT || 5001
app.listen(PORT, () => {
console.log(`Server is Running on http://localhost:${PORT}`)
} )
i really hope this problem solving of this code, thank you
You are calling your API on localhost:3000, but your API should be running on localhost:5001
const { data } = await axios.get("http://localhost:5001/api/products");
You want to initialize your state with brackets "[]" instead of "{}"
const [products, setProducts] = useState([])
Also, you might want to code defensively by adding a turnery operation to check to see if products is 'truthy' if it's not, then the user will see some kind of error message i.e. the part after the ":".
{products ? products.map( product => {}) : <div>handle error</div> }
finally i've got this solve
i miss the set proxy server of the front end site, thanks !
Just you need to do is install cors by using below command:
npm install core
//Then use it in server file like this:
var cors = require('cors')
app.use(cors())

React: How to update the DOM with API results

My goal is to take the response from the Google API perspective and display the value into a div within the DOM.
Following a tutorial : https://medium.com/swlh/combat-toxicity-online-with-the-perspective-api-and-react-f090f1727374
Form is completed and works. I can see my response in the console. I can even store the response into an object, array, or simply extract the values.
The issue is I am struggling to write the values to the DOM even though I have it saved..
In my class is where I handle all the API work
class App extends React.Component {
handleSubmit = comment => {
axios
.post(PERSPECTIVE_API_URL, {
comment: {
text: comment
},
languages: ["en"],
requestedAttributes: {
TOXICITY: {},
INSULT: {},
FLIRTATION: {},
THREAT: {}
}
})
.then(res => {
myResponse= res.data; //redundant
apiResponse.push(myResponse);//pushed api response into an object array
console.log(res.data); //json response
console.log(apiResponse);
PrintRes(); //save the values for the API for later use
})
.catch(() => {
// The perspective request failed, put some defensive logic here!
});
};
render() {
const {flirty,insulting,threatening,toxic}=this.props
console.log(flirty); //returns undefined, makes sense upon initialization but does not update after PrintRes()
return (
<div className="App">
<h1>Please leave a comment </h1>
<CommentForm onSubmit={this.handleSubmit} />
</div>
);
}
}
When I receive a response from the API I use my own function to store the data, for use later, the intention being to write the results into a div for my page
export const PrintRes=() =>{
// apiResponse.forEach(parseToxins);
// myResponse=JSON.stringify(myResponse);
for (var i = 0; i < apiResponse.length; i++) {
a=apiResponse[i].attributeScores.FLIRTATION.summaryScore.value;
b=apiResponse[i].attributeScores.INSULT.summaryScore.value;
c=apiResponse[i].attributeScores.THREAT.summaryScore.value;
d=apiResponse[i].attributeScores.TOXICITY.summaryScore.value;
}
console.log("hell0");//did this function run
// render(){ cant enclose the return in the render() because I get an error on the { , not sure why
return(
<section>
<div>
<p>
Your comment is:
Flirty: {flirty}
</p>
</div>
<div>
<p>
Your comment is:
insulting: {insulting}
</p>
</div>
<div>
<p>
Your comment is:
threatening: {threatening}
</p>
</div>
<div>
<p>
Your comment is:
toxic: {toxic}
</p>
</div>
</section>
);
}
Variables and imports at the top
import React from "react";
//needed to make a POST request to the API
import axios from "axios";
import CommentForm from "../components/CommentForm";
var myResponse;
var apiResponse= [];
let a,b,c,d;
let moods = {
flirty: a,
insulting:b,
threatening:c,
toxic:d
}
If I understand correctly You need to create a state where you store data from api.
States in react works like realtime stores to refresh DOM when something change. this is an example to use it
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
apiData: undefined
};
}
fetchData() {
this.setState({
apiData: "Set result"
});
}
render() {
const { apiData } = this.state;
return (
<div>
<button onClick={this.fetchData.bind(this)}>FetchData</button>
<h3>Result</h3>
<p>{apiData || "Nothing yet"}</p>
</div>
);
}
}
you can check it here: https://codesandbox.io/s/suspicious-cloud-l1m4x
For more info about states in react look at this:
https://es.reactjs.org/docs/react-component.html#setstate

Display response object from GET request on backend in react component

I am still figuring React out and have a question. I want to display some data that I am getting back from my mLab database. When I make the request in Postman to test request i get back the object full of data and now I want to display that data in my component.
Backend/server.js:
//this is tested and works in postman
app.get('/logs', function(req, res) {
user: req.user;
res.json();
});
React action:
export const GET_DATA_SUCCESS = 'GET_DATA_SUCCESS';
export const GET_DATA_TRIGGERED = 'GET_DATA_TRIGGERED';
export const GET_DATA_FAILURE = 'GET_DATA_FAILURE';
export function getData() {
const promise = fetch('http://localhost:8080/logs');
return {
onRequest: GET_DATA_TRIGGERED,
onSuccess: GET_DATA_SUCCESS,
onFailure: GET_DATA_FAILURE,
promise,
};
}
Component where I want to display:
import React from 'react';
import {Router, Route, Link, Redirect, withRouter} from 'react-router-dom';
import { getData } from '../actions/memory';
import { connect } from 'react-redux';
export class oldMemory extends React.Component {
oldSearch(e) {
e.preventDefault();
this.props.getData();
}
render() {
return(
<div className="old-info">
<Link to="/main"><h3 className="title-journey">Travel Journal</h3></Link>
<h4>Retrieve a Memory</h4>
<p className="get-info">Look back on an old place you have visited and
reminisce.</p>
<input className="search" type="text" name="search" placeholder="Search"
/>
<button onClick={this.oldSearch.bind(this)}>Get</button>
// would like data to show up here
</div>
)
}
}
export default connect(null, { getData })(oldMemory)
I would use a state to store the data and set the state after the getData promise is resolved. Then, in the render method, i map the state data to div elements and display them in the the component.
// I assume your result of get Data is an array of
// objects {id: number,date: string, memory: string}
// and that getData is a promise
class OldMemory extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
}
}
oldSearch = (e) => {
e.preventDefault();
this.props.getData().then(data => {
// if data is null, or undefined set it to an empty array
this.setState({ data: data || [] });
})
}
render() {
// build data to div elements for display
const memories = this.state.data.map(d => <div>{d.date} - {d.memory}</div>)
return(
<div className="old-info">
<Link to="/main"><h3 className="title-journey">Travel Journal</h3></Link>
<h4>Retrieve a Memory</h4>
<p className="get-info">Look back on an old place you have visited and
reminisce.</p>
<input className="search" type="text" name="search" placeholder="Search"
/>
<button onClick={this.oldSearch}>Get</button>
// would like data to show up here
<div id="display-data">
{ memories }
</div>
</div>
</div>
);
}
}
export default connect(null, { getData })(OldMemory)

Resources