React: Passing a graphql prop to another component - javascript

I have a dashboard with a table component inside it. I am making a graphql call in the dashboard and need to pass the data recieved into the table like this . However I can't get the data to show up inside the table component.
Here is my approach. Please let me know what I'm missing
Dashboard.js
import React from "react";
import "bootstrap/js/src/collapse.js";
import DashboardTable from "../DashboardTable";
import { API } from "#aws-amplify/api";
import config from "../../aws-exports";
import * as queries from "../../graphql/queries";
export default function Dashboard() {
var opportunityTable;
API.configure(config);
async function asyncCall() {
const opportunityTable = await API.graphql({
query: queries.listMockOppsTables,
});
// console.log(opportunityTable.data.listMockOppsTables); // result: { "data": { "listTodos": { "items": [/* ..... */] } } }
}
asyncCall();
return (
<div>
<div className="container py-5">
<DashboardTable
data={opportunityTable.data.listMockOppsTables}
></DashboardTable>
</div>
</div>
);
}
Table (receiving prop data)
import React from "react";
import "bootstrap/js/src/collapse.js";
require("../opportunityData.json");
export class Opportunity extends React.Component {
constructor(props) {
super(props);
this.state = {
opportunityData: this.props.items,
};
}
render() {
console.log(this.opportunityData);// returns nothing
return (
<div>
<section class="py-5 mt-5">
<div class="container py-5">
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Shadow ID</th>
<th>Role Title</th>
<th>Interview Type</th>
<th>Level</th>
<th>Date and Time</th>
<th># Requests</th>
<th>Make Request</th>
</tr>
</thead>
{this.opportunityData.map((opportunity) => (
<tbody>
<tr>
<td>{opportunity.shadow_id}</td>
<td>{opportunity.job_title}</td>
<td>{opportunity.shadow_type}</td>
<td>4</td>
<td>
{opportunity.shadow_datetime}
<br />
{opportunity.shadow_datetime}
</td>
<td>2</td>
<td>
<div class="btn-group" role="group">
<button
class="btn btn-primary"
type="button"
style={{
backgroundColor: "#ff9900",
border: 0,
}}
>
Shadow
</button>
<button
class="btn btn-primary"
type="button"
style={{
backgroundColor: "#ffac2f",
border: 0,
}}
>
Reverse Shadow
</button>
</div>
</td>
</tr>
</tbody>
))}
</table>
</div>
</div>
</section>
</div>
);
}
}
export default Opportunity;

You're problem is either with your method of passing state or with you querying. One issue in your code is by practice in React, you want state to be managed as a stateful value with the useState()hook. You will have to verify your data is loaded before passing it into the hook. This would look like:
const [opportunityTable, changeOpportunityTable] = useState(asyncCall());
Also you should've posted your DashBoardTable component instead of your Oppurtunity component which you don't seem to import in DashBoard to begin with. Here's a little skeleton
const DashBoardTable = ({data}) => {
//whatever code you may need
return (
//other formatting
data.map((key) => {
//access with data.<VARIABLE>
}
);
}
export default DashBoardTable;

Related

My console shows this error "Uncaught SyntaxError: Cannot use import statement outside a module (at bundle.js:47878:2)". I am building a React app

import axios from 'axios';
import React, { useEffect, useState } from 'react'
import Navbar from './Navbar'
const Home = () => {
var [Employeelist,setEmployeelist] = useState([]);
useEffect(()=>{
getData();
},[])
const getData=()=>{
axios.get('https://jsonplaceholder.typicode.com/users')
.then((response)=>{
console.log(response.data)
setEmployeelist(response.data)
})
.catch()
}
return (
<div>
<Navbar/>
<br /><br />
<div className="container">
<div className="row">
<div className="col col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12 col-xxl-12">
<div className="row g-4">
<div className="col col-12 col-sm-12 col-md-12 col-lg-12 col-xl-12 col-xxl-12">
<h2 style={{textAlign:"center",textDecoration:"underline",fontStyle:'italic'}}>Employee data</h2>
<table class="table table-success table-striped table-hover" style={{border:'solid 2px black', borderRadius:'20px !important'}}>
<thead className="table-dark">
<tr>
<th scope="col">id</th>
<th scope="col">Name</th>
<th scope="col">Email</th>
</tr>
</thead>
{Employeelist.map((value,index)=>{
return <tbody class="table-group-divider">
<tr>
<th scope="row">{value.id}</th>
<td>{value.name}</td>
<td>{value.email}</td>
</tr>
</tbody>
})}
</table>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
export default Home
This is my code
When i start the server it shows compiled successfully but nothing shows on the screen and when i open the console it shows "Uncaught SyntaxError: Cannot use import statement outside a module (at bundle.js:47878:2)" I tried adding "type":"module" into the package.json file as shown inn somethreads but still not useful
The issue is, the browser cannot use modules so you need a bundler like (Browserify or Vite) which bundles your modules and code into a single file so it can be used by the browser. More information about modules and bundlers here

Modal not showing Menu Data

I am trying to make a sample React Modal of Menu in which it must display Menu. So, I already developed its Backend using NodeJS + Express and it works properly. But, after I integrate it to Frontend Page, it does not show any menu data.
import React, {Component} from 'react';
import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';
import 'react-tabs/style/react-tabs.css';
import '../Styles/RestDetails.css';
import {Button} from 'react-bootstrap';
import Modal from 'react-modal';
import axios from 'axios';
import QueryString from 'query-string';
class RestDetails extends React.Component
{
constructor()
{
super();
this.state = {
menus: [],
isModalOpen: false
}
}
componentDidMount()
{
const Qparams = QueryString.parse(this.props.location.search);
const restID = Qparams.id;
axios({
method: 'GET',
url: `http://localhost:4005/api/restaurantMenu/${restID}`,
headers: {'Content-Type' : 'application/json'}
}).then(result => {
this.setState({
menus: result.data.menus
})
}).catch(error => {
console.log(error);
});
}
handleOrder = (event) => {
const {menus} = this.state;
this.setState({
isModalOpen: true
});
}
cancelHandler = (event) => {
this.setState({
isModalOpen: false
});
}
render()
{
const {isModalOpen, menus} = this.state;
return(
<div className="container-fluid">
<div className="row">
<Modal isOpen={isModalOpen} className="modal-dialog modal-lg" id="modal_header">
<div className="modal-content">
<div className="modal-header">
<h3 className="modal-title">MENU</h3>
<button type="button" className="close" onClick={this.cancelHandler}>×</button>
</div>
<div className="modal-body">
<table className="table table-bordered">
<tbody>
<tr>
{
menus.map((item, index) => {
return (
<div className="row">
<td>
<div className="col-6">{item.item}</div>
<div className="col-2">{item.cost}</div>
</td>
<td>
<div className="col-4"><Button>ADD</Button></div>
</td>
<hr/>
</div>
)
})
}
</tr>
</tbody>
</table>
</div>
<div className="modal-footer">
<div className="float-left">Subtotal: 220</div>
<button className="btn btn-primary" onClick={this.Handler}>Order</button>
<button className="btn btn-danger" onClick={this.cancelHandler}>Cancel</button>
</div>
</div>
</Modal>
</div>
)
}
}
export default RestDetails;
Here, the Modal is linked with Button using State Handler and componentDidMount() which is linked to Backend using Axios and Query-String. I checked the Backend using Postman and it able to fetch and display data by entering the restaurant ID. But it can't able to display at the Frontend Modal. Please share some ideas. Thanks in advance.

Uncaught TypeError: $(…).modal is not a function

So, this code is supposed to show JQuery table, and in the third column, every row is clickable and when clicked it shows a Modal.
When i start the code, the table shows, and when i clicked the third row, the alert test works, but the modal didnt show, and in the console it printed an error log:
UnCaught TypeError: topics.jsx
$(...).modal is not a function
So clearly the show modal function in the .click(function()) does not work, some similar questions from StackOverflow is saying that bootstrap.min.js and jquery.min.js is not referenced, but i'm not sure if that is the case because im using those libraries in this page no problem.
How do i fix this?
topics.jsx:
import React from 'react';
import ReactDOM from 'react-dom';
import ReactDOMServer from 'react-dom/server';
import PropTypes from 'prop-types';
import Navbar, { MENU as MAIN_MENU } from '../../components/Navbar';
import TopicFilter from '../../components/TopicFilter';
import PeriodTag from '../../components/PeriodTag';
import LecturerInfo from '../../components/LecturerInfo';
import Layout from '../../components/layouts';
import { Nav, NavItem, NavLink, Collapse, Modal, ModalBody, ModalHeader, Button, Form, FormGroup, FormInput, Alert } from "shards-react";
var $ = require('jquery');
var dt = require('datatables.net')();
class TopicTable extends React.Component {
constructor(props) {
super(props);
$(document).ready(() => {
$('#topic-table').DataTable({
data: this.props.topics || [],
columns: [
{ data: 'id', visible: false }, //id
{ data: 'name' }, //name
{ data: 'quota' }, //quota
{ data: 'deskripsi'}, //DESKRIPSI
{ data: 'kk', visible: false }, //kk
{ data: 'peminatan', render: 'abbrev' }, //peminatan
{ data: 'period', render: 'semester' }, //period
{ //lecturer
data: 'lecturer',
/*render: function(data, type, row, meta) {
if (type=='display') {
const lecturerInfo = (
<LecturerInfo
nik={data.nik}
name={data.name}
lecturerCode={data.lecturerCode}
/>
);
return ReactDOMServer.renderToString(lecturerInfo)
}
}*/
render: 'name'
},
{ data: 'isDeleted', visible: false } //isDeleted
]
})
$('#topic-table').find('td:nth-child(3)').click(function() {
alert($(this).html());
$('#myModal').modal('show'); //FUNCTION TO SHOW MODAL
});
})
}
componentDidUpdate() {
$(function () {
$('[data-toggle="popover"]').popover()
})
}
render() {
return (
<div>
//MODAL
<div class="modal" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Modal Heading</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
Modal body..
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
//TABLE
<table id="topic-table">
<thead>
<tr>
<th bgcolor="#E8E8E8">Id</th>
<th bgcolor="#E8E8E8">Topik</th>
<th bgcolor="#E8E8E8">Quota</th>
<th bgcolor="#E8E8E8">Deskripsi</th>
<th bgcolor="#E8E8E8">KK</th>
<th bgcolor="#E8E8E8">Peminatan</th>
<th bgcolor="#E8E8E8">Semester</th>
<th bgcolor="#E8E8E8">Dosen</th>
<th bgcolor="#E8E8E8">sudah dihapus</th>
</tr>
</thead>
</table>
</div>
)
}
}
TopicTable.propTypes = {
topics: PropTypes.arrayOf(PropTypes.object)
}
function Page() {
const { currentPeriod, topics, peminatanList } = window.SAILS_LOCALS;
return (
<div className="page main-content-container px-4 pb-4 container-fluid">
{/* <Navbar activeMenu={MAIN_MENU.TOPICS} /> */}
<div className="container">
<h2 class="display-4">Daftar Topik <PeriodTag period={currentPeriod} /></h2>
<div>
<TopicFilter peminatanList={peminatanList} />
<TopicTable topics={topics} />
</div>
</div>
</div>
)
}
ReactDOM.render(<Layout><Page /></Layout>, document.getElementById('root'));
jQuery doesn't have a modal method.
There are various plugins which add such a method, including bootstrap.
To use a plugin, you need to register it with jQuery.
In traditional web programming, this is done by:
Adding a <script> element which loads jQuery and creates jQuery and $ as globals.
Adding a <script> element which loads the plugin, which accesses one of those global variables and modifies the object assigned to it.
In your code, you are assigning a value to $ with require. It is locally scoped to the JS module. If you had loaded the Bootstrap JS which would have added the plugin with a <script> in the page then it would have either thrown an error, or associated the plugin with a different copy of the jQuery object.
Since you are working with React, use React Bootstrap which provides things like the Bootstrap Modal as React components.

Conditionally rendering component on button click (React)

I have created a basic React project that is pulling data from a SQL server. I would like this to be able to be rendered conditionally depending on what button has been clicked.
This is my Display Users Component which is used within my AdminViewUsers component (What is actually displaying the users).
import React, { Component } from 'react';
import './customers.css';
class DisplayUsers extends React.Component{
constructor(){
super();
this.state= { users: [] }
}
componentDidMount(){
this.setState({
users: this.getItems()
})
}
getItems(){
fetch('/admin-view-users')
.then(recordset => recordset.json())
.then(results => { console.log(results.recordset); this.setState({'users': results.recordset}); });
}
render () {
console.log(this.state.users)
return (
<ul>
{this.state.users && this.state.users.map(function(user, index){
//if (user.severity === 1){
return(
<div className ="jumbotron">
<li>
Severity: {user.severity}
</li>
<li>
<p>User Name:{user.name} </p>
</li>
<li>
User Email: {user.email}
</li>
<li>
Description of Issue: {user.description}
</li>
<button>See Details</button>
</div>
)
})
}
</ul>
);
}
}
export default DisplayUsers;
This is my AdminViewUsers Component
import logo from '../codestone logo.png';
import {Link } from 'react-router-dom'
import '../bootstrap.min.css'
import '../bootstrap.min.css'
import '../App.css'
import Customers from "../Components/customers";
import DisplayUsers from "../Components/DisplayUsers";
import { ButtonDropdown, DropdownToggle, DropdownMenu, DropdownItem, DropDownButton } from 'reactstrap';
function Home() {
return (
<div>
<Header/>
<SeveritySelector/>
<DisplayUsers/>
</div>
);
}
function Header(){
return (
<div class="jumbotron">
<div className = "User-Menu">
<Link>User details </Link>
</div>
<img className='profile-image' alt='icon' src={logo} width="340" height="60"/>
<Navigation/>
</div>
)
}
function Navigation (){
return(
<div>
<br/>
<div class="btn-group">
<Link to= '/home'><button type="button" class="btn btn-light">Home</button></Link>
<Link to= '/admin-view-users'><button type="button" class="btn btn-light">View Users(Admin)</button></Link>
</div>
</div>
)
}
function SeveritySelector (){
return(
<div className = "Severity-Toolbar">
<div class="btn-toolbar" role="toolbar" aria-label="Toolbar with button groups">
<div class="btn-group mr-2" role="group" aria-label="First group">
<button type="button" class="btn btn-secondary">Severity High</button>
<button type="button" class="btn btn-secondary">Severity Medium</button>
<button type="button" class="btn btn-secondary">Completed</button>
<button type="button" class="btn btn-secondary">View All</button>
</div>
</div>
</div>
)
}
export default Home;
Essentially I would like to use the function Severity Selector to be the decider of how the statement is displayed.E.g If the high severity button is selected then it will display all with a high severity (1) if medium selected all with medium severity (2) and completed to have a severity of 3. Finally a button to display all.
What in your opinion is the best way to do this? I understand I could use multiple statements within my "server.js" and load different queries and have them connected to different pages.
But is there a way that I could just use a if statement or something similar to determine what button is selected to avoid multiple transactions with the server? You can see a brief attempt I had within the display users with an if statement which worked but just was not dependent on the buttons.
Conditional render can be achieved using various techniques, the most used is the bracket style variant. It can be used in the following way:
function Header(){
const showFirst = true;
return (
<div class="jumbotron">
{showFirst && <MyFirstComponent />}
{!showFirst && <MySecondComponent />}
</div>
)
}
This will render the <MyFirstComponent /> if showFirst is true and will show <MySecondComponent /> if it is false.

Javascript, html and react js. error in calling this.state.filteredUsers.map ((user)

I have to make a modal within which I have to perform a search and complete the imput that you give me. The information I look for in an api, here is the code:
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends React.Component {
constructor (props) {
super(props);
this.setState = {
users: [],
filteredUsers: []
};
}
componentDidMount () {
fetch('/users')
.then((resp) => resp.json())
.then((users) => {
this.setState({ users });
})
.catch(function(error) {
console.log(error);
});
}
search (e) {
let value = e.target.value;
// hace un filtrado del array de usuarios para obtener
// aquellos cuyo nombre contiene lo ingresado en el input
let filteredUsers = this.state.users.filter((user) => {
return user.name.includes(value);
});
// actualiza el estado y por ende, la tabla
this.setState({
filteredUsers
});
}
render() {
return (
<div className="App">
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
<button type="button" className="btn btn-info btn-lg" data-toggle="modal" data-target="#myModal">Open Modal</button>
<div id="myModal" className="modal fade" role="dialog">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal">×</button>
<h4 className="modal-title">Add Note</h4>
</div>
<div className="modal-body">
<h5 className="modal-title">New Note </h5>
<input
type="text"
id="myInput"
name="search"
placeholder="Search.."
title="Type in a name"
onChange={this.search.bind(this)}
></input>
<table>
<thead>
<tr>
<th>Name</th>
<th>Username</th>
<th>Email</th>
<th>Address</th>
<th>Phone</th>
<th>Company</th>
<th>website</th>
</tr>
</thead>
<tbody>
{
this.state.filteredUsers.map((user) => (
<tr>
<td>{user.name}</td>
<td>{user.username}</td>
<td>{user.email}</td>
<td>{user.address}</td>
<td>{user.phone}</td>
<td>{user.company}</td>
<td>{user.website}</td>
</tr>
))
}
</tbody>
</table>
</div>
<div className="modal-footer">
Import: <input type="checkbox" id="myCheck"></input>
<button type="button" className="btn btn-default" data-dismiss="modal">Add Note</button>
<button type="button" className="btn btn-default" data-dismiss="modal">cancelar</button>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default App;
In theory the code should do is find the info in the api and go autocompleting, everything works fine until I put the body of the table, when I add that block of code I try to run the program the only thing I get is a white screen and I do not know why.
To the moment that I remove that block of code the program runs perfect
What is happening in that block of code that does not render anything?
The first thing I see is that you don't have a key attribute in your loop elements, it should be something like this:
this.state.filteredUsers.map((user, index) => (
<tr key={index}>
...
</tr>
));
Also bear in mind that react will not guarantee that the state will be updated immediately:
setState() does not immediately mutate this.state but creates a
pending state transition. Accessing this.state after calling this
method can potentially return the existing value. react docs
This here is a great article that could help you understand more the problem. 3 Reasons why I stopped using React.setState

Categories