React app - how to identify undefined object in the code? - reactjs

I am new to React, so hopefully it's not a silly question but I have been getting the error below when I ran the code.
I believe the error is related to one of the two files' codes below. Can someone help me to see where I'm making a mistake?
App.js file:
import React from 'react';
import './App.css';
import BusinessList from '../BusinessList/BusinessList';
import SearchBar from '../SearchBar/SearchBar';
const business = { imageSrc:
'https://s3.amazonaws.com/codecademy-content/programs/react/ravenous/pizza.jpg',
name: 'MarginOtto Pizzeria',
address: '1010 Paddington Way',
city: 'Flavortown',
state: 'NY',
zipCode: '10101',
category: 'Italian',
rating: 4.5,
reviewCount: 90};
const businesses = [business,business,business,business,business,business];
class App extends React.Component {
render() {
return (
<div className="App">
<h1>ravenous</h1>
<SearchBar />
<BusinessList businesses={businesses} />
</div>
);}}
export default App;
Business.js file:
import React from 'react';
import './Business.css';
import '../App/App'
class Business extends React.Component {
render() {
const { business } = this.props;
return (
<div className="Business">
<div className="image-container">
<img src='https://s3.amazonaws.com/codecademy-content/programs/react/ravenous/pizza.jpg' alt=''/>
</div>
<h2>{business.name}</h2>
<div className="Business-information">
<div className="Business-address">
<p>{business.address}</p>
<p>{business.city}</p>
<p>{business.state} {business.zipCode}</p>
</div>
<div className="Business-reviews">
<h3>{business.category}</h3>
<h3 className="rating">{business.rating} stars</h3>
<p>{business.reviewCount} reviews</p>
</div>
</div>
</div>
);
}
}
export default Business;

The error seems to be in your BusinessList component.
you pass this.business as a prop to Business but it should just be business (the name of the parameter use in the .map function)
import React from "react";
import "./BusinessList.css";
import Business from "../Business/Business";
class BusinessList extends React.Component {
render() {
return (
<div className="BusinessList">
{this.props.businesses.map(business => {
return <Business business={business} />;
})}
</div>
);
}
}
export default BusinessList;

In Business.js file try to change code like this
return business && (
...
);
if business is undefine then it returns null.
Or if it doesn't work try to use ?: operator like
return business ? (...) : null;
Hope this help you to resolve issue

Related

Best way to output a very simple menu in react

I'm new to react and my question is extremely simple. I want to just know the best way to output a navigation menu on a page (i.e. literally just page links).
So my main app.js has this code:
import React, {Component} from "react";
import NavMenu from "./nav-menu";
const theLinks = [
"home",
"subs"
]
export default class App extends Component {
constructor() {
super();
this.state = {
navLinks: theLinks
}
}
render() {
return (
<div id="container">
<NavMenu navLinks={this.state.navLinks} />
</div>
);
}
}
And the nav-menu component has this code:
import React, {Component} from "react";
export default class navBar extends React.Component {
render() {
return (
this.props.navLinks.map((c, i) => <a href={c[1]} key = {i} > {c[0]} </a>)
)
}
}
Which should (but doesn't) output is like this:
<div id="container"> home subs </div>
Why is this not outputting like the above? My gut feeling also senses that this is not a good way to output a menu or list of links. What is a better way?
Thanks for any advice here. I'm trying to learn react pragmatically and without having to study a long course.
Stackblitz: https://stackblitz.com/edit/react-hunbng?file=src%2FApp.js
Your array has quite a strange structure. I'd go for something more readable/usable:
App.js
import React, {Component} from "react";
import NavMenu from "./nav-menu";
const theLinks = [
{
name: "home",
href: "/index"
},
{
name: "subs",
href: "/subs"
},
]
export default class App extends Component {
constructor() {
super();
this.state = {
navLinks: theLinks
}
}
render() {
return (
<div id="container">
<NavMenu navLinks={this.state.navLinks} />
</div>
);
}
}
nav-menu.js
import React, {Component} from "react";
export default class navBar extends React.Component {
render() {
return (
// it's considered bad practice to use the map-index as a key, hence the href as key
this.props.navLinks.map((c) => <a href={c.href} key={c.href} > {c.name} </a>)
)
}
}

Creating a new room (including inputs and button) and only template shows without the values inside (rcc)

At the button click Create I want to display the room with the content (the new values ​​that holds by the objects in the array - the value I wrote inside the inputs) but fro some reason it's not working and I can't solve it, the problem is that only the template that shows the titles Room and Type are shown without the values inside each of them
Thanks to the helpers!
App.js
import React, { Component } from 'react'
import './App.css';
import Addroom from './components/Addroom.js'
import Room from './components/Room.js'
import 'bootstrap/dist/css/bootstrap.css';
export default class App extends Component {
state={roomsList:[{room:'',type:''}]
}
create=(r,t)=> {
this.setState({roomsList:[...this.state.roomsList,{room:r,type:t}]})
}
render() {
return (
<div>
<h1>My Smart House</h1>
{this.state.roomsList.map((element)=>{
return <Room r={element.room} t={element.type} />
})}
<Addroom add={this.create}/>
</div>
)
}
}
Addroom.js
import React, { Component } from 'react'
export default class Addroom extends Component {
constructor(props) {
super(props)
}
addRoomName=(e)=> {
this.setState({room:e.target.value})
}
addType=(e)=> {
this.setState({type:e.target.value})
}
createRoom=()=> {
this.props.add(this.state.room,this.state.type);
}
render() {
return (
<div>
<input onChange={this.addRoomName} placeholder='Name Your Room'/><br/>
<input onChange={this.addType} placeholder='Whats The Room Type?'/><br/>
<button onClick={this.createRoom}>Create</button>
</div>
)
}
}
Room.js
import React, { Component } from 'react'
export default class Room extends Component {
constructor(props) {
super(props)
this.state = {
}
}
render() {
return (
<div>
<h1>Room: {this.props.room} </h1>
<h3>Type: {this.props.type} </h3>
</div>
)
}
}
I solved the error, it was a syntax mistake, so what i did, I just asked to get the inside value from my objects in the Room.js components, So it looked like that before:
render() {
return (
<div>
<h1>Room: {this.props.room} </h1>
<h3>Color: {this.props.type} </h3>
</div>
)
}
}
and now I just fixed the syntax to make App.js component understand that I want to display the values inside the objects when I'm creating a new room with my button, because now r and t are represent the values of the variables..
render() {
return (
<div>
<h1>Room: {this.props.r} </h1>
<h3>Color: {this.props.t} </h3>
</div>
)
}
}
This is a very small mistake that is easy to understand, so it is always important to go through your code slowly and safely! Hope it will help some f.e devs in the future..

Show Detail Component with React-Router

I am learning react-router and trying to display a list of courses and course detail. But now, the CourseDetail2 component page does not display. Help!
App.js
`
import React, { Component } from 'react';
import axios from 'axios';
import CourseList2 from './components/CourseList2'
//campus data
const campusData = [
{ id: 1, value:'A',name: 'A' },
{ id: 2, value:'B',name: 'B' },
{ id: 3, value:'C',name: 'C' }
]
class App extends Component {
state={campus:null,
Courses:[]}
componentDidMount(){
//api call
setState={Courses:response.data}
}
//event handler
handleCampusChkChange()=>{
//code
}
render() {
return (
<div className="App">
<Campus key={item.id} {...item} onChange={this.handleCampusChkChange} />
<CourseList2 courses={this.state.Courses}/>
</div>
);
}
}
export default App;
`
CourseList2.js
import React from 'react';
import CourseDetail2 from './CourseDetail2';
import {BrowserRouter as Router, Route, Link,Redirect} from 'react-router-dom';
import './CourseItem.css';
import App from './App';
const CourseList2=({Courses})=>{
console.log("coruses="+Courses);
const renderedList= Courses.map(course=>{
return (<div className="item" >
<div class="content">
<div class="header">
<h4>
{course.SUBJECT} {course.CATALOG} {course.DESCR}
</h4> </div>
<Link to={{ pathname: 'course/'+course.ID}}
key={course.ID}>
View More
</Link>
</div>
</div>
)
});
return (
<Router><div className="List ui relaxed divided list">
{renderedList}
<Route path="course/:course.ID" component={CourseDetail2} />
</div></Router>);
}
export default CourseList2
CourseDetail2.js
import React, { Component } from 'react';
class CourseDetail2 extends Component {
render(){
return (
<div>
Course Detail: CLASS ID {this.props.match.params.ID}
</div>
);
}
};
export default CourseDetail2;
Adding as answer instead of comment.
Probably want to pass this.state.Courses to CourseList2, and wrap CourseDetails2 with withRouter HOC from react-router-dom so it can access the route match prop.
Also, the path in the route in CourseList2 should probably be path="course/:ID" since that is how you access it on the details.
location, match and history objects can only be accessed when you wrap the component with the higher order component withRouter.
Right now you don't have access to this.props.match in CourseDetail2 component.
import React, { Component } from 'react';
import {withRouter} from 'react-router';
class CourseDetail2 extends Component {
render(){
return (
<div>
Course Detail: CLASS ID {this.props.match.params.courseID}
</div>
);
}
};
export default withRouter(CourseDetail2);
Also the string after : doesn't have match with the code. It can be anything.
<Route path="course/:courseID" component={CourseDetail2} />
And you access using that string name in your code.

TypeError: robots.map is not a function

I keep getting this error: TypeError: robots.map is not a function.
I reviewed the code several times can't find the bug.
import React from 'react';
import Card from './Card';
// import { robots } from './robots';
const CardList = ({ robots }) => {
return(
<div>
{
robots.map((user, i) => {
return (
<Card
key={i}
id={robots[i].id}
name={robots[i].name}
email={robots[i].email}
/>
);
})
}
</div>
);
}
export default CardList;
App.js
import React, { Component } from 'react';
import CardList from './CardList';
import SearchBox from './SearchBox';
import { robots } from './robots';
class App extends Component {
constructor(){
super()
this.state = {
robots:'robots',
searchfield: ''}
}
render(){
return(
<div className='tc'>
<h1 className=''>RoboFriends</h1>
<SearchBox />
<CardList robots={this.state.robots}/>
</div>
);
}
}
export default App;
I updated the initial code with App.js that calls CardList.
I recently started learning react and I hope to develop an app that lets you search for a user which instantly filters and render the name typed in the search box.
You pass robots as props from App internal state and not from the imported file.
Set the state of App component from the imported robots file
import { robots } from './robots'
class App extends Component {
constructor() {
super()
this.state = {
robots,
searchfield: ''
}
}
render() {
return (
<div className='tc'>
<h1 className=''>RoboFriends</h1>
<SearchBox />
<CardList robots={this.state.robots}/>
</div>
);
}
}
Also using index as React key is a bad practice, You have a unique id in every robot object so use it as key, also read about the map function and how to access the iterated elements
const CardList = ({ robots }) => (
<div>
{robots.map(robot => (
<Card
key={robot.id}
id={robot.id}
name={robot.name}
email={robot.email}
/>
))}
</div>
);
You're passing a string to be mapped, instead pass the robots list of objects and see the result.
These kind of errors are the result of passing something other than a list to be mapped

React and d3-graphviz

I'm trying to render a graphviz graph from a dotfile in my React Component. I keep running into errors I don't understand. If anyone could shed some light I would be grateful.
import React from 'react';
import dotSrc from '../../assets/visualize_dotfile.dot';
import Viz from 'viz.js';
import * as d3 from 'd3'
import * as d3Graphviz from 'd3-graphviz';
class Visualization extends React.Component {
setGraph() {
console.log('DOT source =', dotSrc);
const dotSrcLines = dotSrc.split('\n');
d3.select(".graph").graphviz().renderDot(dotSrc);
}
render(){
return (
<div className="graph">
{this.setGraph}
</div>
)
}
}
export default Visualization;
I've also tried:
import React, { Component } from 'react';
import { render } from 'react-dom';
import dotSrc from '../../assets/visualize_dotfile.dot';
import Viz from 'viz.js';
import HTMLReactParser from 'react-html-parser';
const graph = Viz({ files: [ { path: dotSrc } ] });
class Visualization extends Component {
constructor() {
super();
this.state = {
name: 'React'
};
}
render() {
return (
<div>
<div>
{HTMLReactParser(graph)}
</div>
</div>
);
}
}
render(<Visualization />, document.getElementById('root'));
To no avail. Neither Viz nor GraphViz wants to read my dotfile though I'm not sure I'm using the correct syntax either.
Thank you in advance.
It's not exactly clear what you want to do and what errors you are getting.
This code at least generates a graph from a static string when the button is clicked:
import React, { Component } from 'react';
import * as d3 from 'd3'
import * as d3Graphviz from 'd3-graphviz';
var dotSrc = 'digraph {a -> b}';
class App extends Component {
setGraph() {
console.log('DOT source =', dotSrc);
d3.select(".graph").graphviz().renderDot(dotSrc);
}
render() {
return (
<div className="App">
<header className="App-header">
<h1 className="App-title">Welcome to magjac's React hack</h1>
</header>
<script src="https://unpkg.com/viz.js#1.8.0/viz.js" type="javascript/worker"></script>
<div className="graph">
</div>
<button className="square" onClick={() => this.setGraph()}>
{'Click me'}
</button>
</div>
);
}
}
export default App;

Resources