Conditional statement within react render meth - reactjs

I am new to react and I am trying to add a condition within the render method so that if the value framework1 is empty I need not add a text within the HTML.
Below is my code.
buildResults = () => {
const {
results
} = this.state;
return {
<div className={`${block}__results`}>
<table>
<thead></thead>
<tbody>
{ results.map(item => this.buildResult(item)) }
</tbody>
</table>
</div>
}
buildResult = (data) => {
const {
framework1,
framework2
} = data;
return (
<tr className={`${block}__row`}>
<td className={`${block}__cell ${block}__cell--ticker`}>
/* I need to display the text "view" only if framework1 is not empty */
View
</td>
</tr>
)
}

Use an if statement to check whether the there is data, in this case, I am checking whether the data in framework1 is a string.
buildResults = () => {
const {
results
} = this.state;
return {
<div className={`${block}__results`}>
<table>
<thead></thead>
<tbody>
{ results.map(item => this.buildResult(item)) }
</tbody>
</table>
</div>
}
buildResult = (data) => {
const {
framework1,
framework2
} = data;
return (
<tr className={`${block}__row`}>
<td className={`${block}__cell ${block}__cell--ticker`}>
if (framework1.indexOf("ST1") ){
// display something else
}
else {
View
}
</td>
</tr>
)
}

Related

display icon based on file type

I want to display icons based on the file type. From the object that I am fetching from strapi I can get the file extension. But I want to render it dynamically on the table.
const TableData = () => {
const [data, setData] = useState([]);
const getData = () => {
axios.get("http://localhost:1337/document-uploads").then((response) => {
console.log(response);
const myData = response.data;
setData(myData);
});
};
useEffect(() => getData(), []);
return (
<div className="my-5">
<Table striped bordered hover>
<thead>
<tr>
<th>Icon</th>
<th>File Name</th>
<th>Description</th>
<th>Author</th>
<th>Date created</th>
</tr>
</thead>
<tbody>
{data &&
data.map((file: File) => (
<tr key={file.id}>
<td>
{() => {
if (file.document.ext == ".pdf") {
return <img src={PDF} />;
} else if (file.document.ext == ".xml") {
return <XML />;
} else {
return <JPEG />;
}
}}
</td>
<td>{file.document.name}</td>
<td>{file.description}</td>
<td>{file.author}</td>
<td>{file.created_at}</td>
</tr>
))}
</tbody>
</Table>
</div>
);
};
export default TableData;
I am getting the error: "Warning: Functions are not valid as a React child. This may happen if you return a Component instead of from render. Or maybe you meant to call this function rather than return it."
You can try the code without the anonymous function inside, just start from the if statement without everything wrapped inside a function.
{
if (file.document.ext == ".pdf") {
return <img src={PDF} />;
} else if (file.document.ext == ".xml") {
return <XML />;
} else {
return <JPEG />;
}
}
You can as well try different approaches with more modern javascript and ternary operators:
{
file.document.ext == ".pdf" ? <img src={PDF} /> :
file.document.ext == ".xml" ? <XML /> : <JPEG />
}
Which is the same as the first code block.

How to Access Variable Outside of Return in a Child from Parent?

If I keep my buttons in my child, this works great except for the fact I have buttons showing in every row. I'd like to move my buttons to the parent so that they just display once at the bottom of the screen. I'v tried moving my buttons to the return on the parent and putting my state code above the return. I think this would work except that my "count" value in my child, for my graphql variable "offset", now needs access to the "count" in my parent. Not sure how to make this happen. I'm pretty new to react and graphql.
import React, { Component, useState } from 'react';
import { useQuery, gql } from '#apollo/client';
import {Table, Spinner, Button} from 'react-bootstrap'
const Customer_List = gql`
query getCust ($configID: Int, $first: Int, $offset: Int ) {
docsconfig (configID:$configID first:$first offset:$offset) {
SubDomain
ConfigID
CustID
customers {
FirstName
LastName
}
}
}
`
function CustomerList() {
const { loading, error, data} = useQuery(Customer_List, {
variables: {
configID: 1436,
first: 10,
offset: count
},
}
);
if (loading) return <td> <Spinner animation="border" role="status">
<span className="sr-only">Loading...</span>
</Spinner> </td>
if (error) return <p>Error :(</p>;
return data.docsconfig.map(({ CustID, SubDomain, customers, FirstName, LastName}) => (
<tr key={CustID}>
<td>{customers.FirstName}</td>
<td>{customers.LastName}</td>
<td>{SubDomain}</td>
</tr>
)
)
}
function Customers () {
const [count, setCount] = useState(0)
function increase() {
setCount(count + 10);
}
function decrease() {
setCount(count - 10);
if (count === 0) {
setCount(count + 0);
}
}
return (
<Table striped bordered hover>
<thead >
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>SubDomain</th>
</tr>
</thead>
<tbody>
<CustomerList />
</tbody>
<tr>
<button onClick={decrease}>-</button>
<button onClick={increase}>+</button>
</tr>
</Table>
);
}
export default Customers;
Pass count as a prop to CustomerList.
CustomerList
function CustomerList({ count }) { // <-- desctructure count from props
const { loading, error, data} = useQuery(
Customer_List,
{
variables: {
configID: 1436,
first: 10,
offset: count // <-- pass to config/options
},
}
);
...
Customers
function Customers () {
const [count, setCount] = useState(0)
...
return (
<Table striped bordered hover>
<thead >
...
</thead>
<tbody>
<CustomerList count={count} /> // <-- pass count to CustomerList
</tbody>
<tr>
<button onClick={decrease}>-</button>
<button onClick={increase}>+</button>
</tr>
</Table>
);
}

How to display button opposite of level in React?

How to display button opposite of its status. Suppose its showing open then the button should appear Withdraw and if the status is appearing Withdraw button should appear Open in Reactjs.
I have a Json object which carries the necessary information.
Here is code is what I have had tried..
const initial = {
description: [
{
name: 'Alex',
level: 'open',
},
{
name: 'Sycus',
level: 'open',
},
{
name: 'Rasku',
level: 'Withdraw',
}
]
}
export default function App() {
const [state, setState] = React.useState(initial)
const [show , setshow] = React.useState(true)
const handleClick = () => {
return
}
const butFunction = () => {
return state.description.map(sub => {
const { level } = sub
return (
if(level === 'open'){
<button>Withdraw</button>
}
else{
<button>Open</buton>
}
)
})
}
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<div>
<table>
<tbody>
{
state.description.map(desc => (
<tr>
<td>
{desc.name}
</td>
<td>
{desc.level}
</td>
<td>
{ show && butFunction()}
</td>
</tr>
))
}
</tbody>
</table>
</div>
</div>
);
}
Instead of rendering two different buttons for two conditions you can use ternary operator to conditionally change the text of single button like this:
return(
<button>{level===‘open’?’withdraw’:’open’}</button>
)
I don't think you need the map inside the butFunction. That would print 3 buttons for every entry. Instead, pass the function a parameter telling it which level it is.
Example below:
export default function App() {
const [state, setState] = React.useState(initial)
const [show , setshow] = React.useState(true)
// Use the level passed in
const butFunction = (level) => {
if(level === 'open'){
return <button>Withdraw</button>;
} else {
return <button>Open</button>;
}
}
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<div>
<table>
<tbody>
{state.description.map(desc => (
<tr>
<td>
{desc.name}
</td>
<td>
{desc.level}
</td>
<td>
{show && butFunction(desc.level)} // <- Pass it here
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
}
Not it will only return one button per entry.

How to display the list response which inside the object - react js

How to display the data in the below from the below json.
{
"a":
{
"b":[
{"id":"ef718cce-1269-4fbd-827c-832f7824c025","name":"Veera6"},
{"id":"0cda5ae9-e287-4666-804a-03f25e642d1f","name":"Veera9"},
{"id":"31f8f042-dbc0-4dbf-ada8-b94c7e2d2a39","name":"Veera8"},
{"id":"6292054c-8bfc-4d2d-b2f8-92e2bac5a578","name":"Veera7"},
{"id":"c6756e5c-8fa5-40a9-ab92-5242bda97de3","name":"Veera10"}]
}
}
code snipped below.
render() {
return (
<table>
<thead>
<tr>
{
this.headers.map(function(h) {
return (
<th key = {h.key}>{h.label}</th>
)
})
}
</tr>
</thead>
<tbody>
{
this.state.tags.b.map(function(item, key) {
return (
<tr key = {key}>
<td>{item.id}</td>
<td>{item.name}</td>
</tr>
)
})
}
</tbody>
</table>
)
}
}
How to display the data in table. Here i need to get the array/list b. Tried different approaches to get the data from the object array but no luck.
Don't know what you were going to do in first < tr >.
Maybe this will point you to the right direction.
import React from "react";
import "./styles.css";
const headers = {
a: {
b: [
{ id: "ef718cce-1269-4fbd-827c-832f7824c025", name: "Veera6" },
{ id: "0cda5ae9-e287-4666-804a-03f25e642d1f", name: "Veera9" },
{ id: "31f8f042-dbc0-4dbf-ada8-b94c7e2d2a39", name: "Veera8" },
{ id: "6292054c-8bfc-4d2d-b2f8-92e2bac5a578", name: "Veera7" },
{ id: "c6756e5c-8fa5-40a9-ab92-5242bda97de3", name: "Veera10" }
]
}
};
let keys = Object.getOwnPropertyNames(headers.a.b[0]);
let head = keys.map(propertyName => <th key={propertyName}>{propertyName}</th>);
export default function App() {
return (
<table>
<thead>
<tr>{head}</tr>
</thead>
<tbody>
{headers.a.b.map(function(item, key) {
return (
<tr key={key}>
<td>{item.id}</td>
<td>{item.name}</td>
</tr>
);
})}
</tbody>
</table>
);
}
So you should access b with headers.a.b and then map().
Your b array is nested inside the headers a object, which is nested in headers object.
Result will be:
id name
ef718cce-1269-4fbd-827c-832f7824c025 Veera6
0cda5ae9-e287-4666-804a-03f25e642d1f Veera9
31f8f042-dbc0-4dbf-ada8-b94c7e2d2a39 Veera8
6292054c-8bfc-4d2d-b2f8-92e2bac5a578 Veera7
c6756e5c-8fa5-40a9-ab92-5242bda97de3 Veera10
Also be sure to check sandbox demo out.
Try this once :
{
this.state.tags.a.b.map(function(item, key) {
return (
<tr key = {key}>
<td>{item.id}</td>
<td>{item.name}</td>
</tr>
)
})
}
Hope it helps. feel free for doubts
Try this
this.state.tags.a.b.map
import React from 'react';
import './App.css';
import { useQuery } from '#apollo/react-hooks';
import gql from "graphql-tag";
const GET_GRPHQL_API = gql`
{
getTags
{
id
tagName
tagDesc
tagVersion
tagVersion
}
}
`
function App() {
const { data, loading, error } = useQuery(GET_GRPHQL_API);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error</p>;
return (
<React.Fragment>
<table>
<thead>
</thead>
<tbody>
{data &&
data.getTags &&
data.getTags.map(function(item, key) {
return (
<tr key={key}>
<td>{item.id}</td>
<td>{item.tagName}</td>
<td>{item.tagDesc}</td>
<td>{item.tagVersion}</td>
</tr>
);
})}
</tbody>
</table>
</React.Fragment>
);
}
export default App;

how to attach key press event on table cell in react js

i have a table i wanna attach arrow keys to each cell wanna implement something like https://jsfiddle.net/rh5aoxsL/ in react but then not able to do so as some where m going wrong can anyone lemme know what has to be done
import React, { Component } from 'react';
import './App.css';
class App extends Component {
constructor(props){
super(props);
this.escFunction = this.escFunction.bind(this);
}
escFunction(event){
if(event.keyCode === 37) {
console.log("----------37---------------");
}
if(event.keyCode === 38) {
console.log("----------38---------------");
}
if(event.keyCode === 39) {
console.log("----------39---------------");
}
if(event.keyCode === 40) {
console.log("----------40---------------");
}
}
componentDidMount(){
document.addEventListener("keydown", this.escFunction, false);
}
componentWillUnmount(){
document.removeEventListener("keydown", this.escFunction, false);
}
render() {
return (
<div className="App">
<table >
<tbody>
<tr>
<td id="start" onKeyDown={this.escFunction}>1</td>
<td onKeyDown={this.escFunction}>2</td>
</tr>
<tr>
<td onKeyDown={this.escFunction}>3</td>
<td onKeyDown={this.escFunction}>4</td>
</tr>
</tbody>
</table>
</div>
);
}
}
export default App;
any help is appreciated
This is my code, just getting siblings.
Constants:
const UP_ARROW = 38;
const DOWN_ARROW = 40;
const LEFT_ARROW = 37;
const RIGHT_ARROW=39;
const TOTAL_CELLS_BY_ROW = (your_number_of_cols);
I have tr -> td -> div -> input, my focus is in inputs. (this is why i have some parentElement and childNodes.
TOTAL_CELLS_BY_ROW is my col count...
onKeyDown = (e) => {
var idx = e.target.parentElement.parentElement.cellIndex;
if (e.keyCode === LEFT_ARROW) {
if (e.target.parentElement.parentElement.previousElementSibling) {
e.target.parentElement.parentElement.previousElementSibling.childNodes[0].childNodes[0].focus();
}
}
if (e.keyCode === RIGHT_ARROW) {
if (e.target.parentElement.parentElement.nextElementSibling) {
e.target.parentElement.parentElement.nextElementSibling.childNodes[0].childNodes[0].focus();
}
}
if (e.keyCode === DOWN_ARROW) {
const nextRow = e.target.parentElement.parentElement.parentElement.nextElementSibling
if (nextRow) {
nextRow.childNodes[idx%TOTAL_CELLS_BY_ROW].childNodes[0].childNodes[0].focus();
}
}
if (e.keyCode === UP_ARROW) {
const previousRow = e.target.parentElement.parentElement.parentElement.previousElementSibling
if (previousRow) {
previousRow.childNodes[idx%TOTAL_CELLS_BY_ROW].childNodes[0].childNodes[0].focus();
}
}
}
Of course onKeyDown={this.onKeyDown} in each input.
I don't know this code is enough for you but as #Pardeep Dhingra explained in the comments you need onKeyDown instead of onKeyPress in your situation. Also, you should change your callback function. I've used tabIndex to start the initial move.
class App extends React.Component {
escFunction = ( event ) => {
if ( event.keyCode === 37 ) {
console.log( "----------37---------------" );
}
if ( event.keyCode === 38 ) {
console.log( "----------38---------------" );
}
if ( event.keyCode === 39 ) {
console.log( "----------39---------------" );
}
if ( event.keyCode === 40 ) {
console.log( "----------40---------------" );
}
}
render() {
return (
<div className="App">
<table>
<tbody>
<tr>
<td id="start" tabIndex="0" onKeyDown={this.escFunction}>
1
</td>
<td onKeyDown={this.escFunction}>2</td>
</tr>
<tr>
<td onKeyDown={this.escFunction}>3</td>
<td onKeyDown={this.escFunction}>4</td>
</tr>
</tbody>
</table>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById("root")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Resources