React rendering string after function with logic/looping - reactjs

Hi I want to render a string with looping logic behind it so I decided to put a function that will return the string
function Leasing(){
let {idLeasingExact} = useParams()
const checkParam = () =>{
//return(idLeasingExact)
dropdownItems.map((item,index) => {
if(idLeasingExact == item.path){
console.log(idLeasingExact)
console.log(item.path)
console.log(item.title)
return(
item.title
)
}
})
}
return(
<div>
<h1>
{idLeasingExact ? checkParam() : "Leasing"
}
</h1>
</div>
)
}
export default Leasing;
here is the dropdown item
export const dropdownItems = [
{
title:'SMF',
path:'1',
cName:'dropdown-link'
},
{
title:'BFI',
path:'2',
cName:'dropdown-link'
},
{
title:'ADIRA',
path:'3',
cName:'dropdown-link'
}
]
I use param and that param will be used in function checkParam to return the result
the checkParam() should return the title(SMF BFI ADIRA) as the result
for example, if it's leasing/1
it should've return the title of SMF
or if it's leasing/2
it should've returned the title of BFI
but it returns null,
although the console log on the browser shows the right item.title just like the example
help appreciated I'm stuck here thanks

So you're not wanting to actually do a map. You gotta find the item on dropdownItems with path equals to idLeasingExact. Try changing your checkParam() function to something like this:
const checkParam = () => {
const item = dropdownItems.find(x => x.path == idLeasingExact);
if (item) return item.title;
else {
// do whatever you want if path is not found, for example:
return 'No title found.'
}
}
What your code is doing, is some sort of a conditional mapping and the function checkParam() is not actually returning something if you take a close look (the function inside the map does return the .title, not the checkParam()!)

map() returns a list. checkParam() is not returning that list. Just add return to the function-
const checkParam = () =>{
return dropdownItems.map((item,index) => {
if(idLeasingExact == item.path){
return(
item.title
)
}
})
}
Also, you can add your JSX logic in checkParam itself like this-
const checkParam = () => {
return dropdownItems.map((item, index) => {
if (idLeasingExact == item.path) {
return <h1>{item.title}</h1>
} else {
return <h2>{"Leasing"}</h2>
}
})
}
return <div>{checkParam()}</div>
This will give you more control based on idLeasingExact value (e.g. conditional styling)

Related

Undefined when selecting div with information

Having an issue with a piece of my code. I fetch from flask server, and display with div in React. I want to select the div and have that information pass to a new object array to return back to flask, but I keep getting undefined.
Code snippet:
function PLCPage() {
const [myjunk, setMyjunk] = useState([]);
const [devList, setDevList] = useState ([]);
const Scan = () => {
fetch('/api/home').then(response => {
if(response.status === 200){
return response.json()
}
})
.then(data => setMyjunk(data))
.then(error => console.log(error))
}
const Clear = () => {
setMyjunk({})
}
Creating the divs:
{Object.keys(myjunk).map((key) =>{
return (
<div className='plc-container' key={key} onClick={ReadStuff}>
<h1>ID:{myjunk[key]['name']}</h1>
<h1>IP:{myjunk[key]['IP']}</h1>
</div>
)
Clicking on the div, just to return a console log returns undefined.
const ReadStuff = () => {
console.log(this.IP)
}
I eventually want to return the data I have in the 2 h1 tags to a new object (devList) but I can't even get it to console log. Sorry if this is basic but I've been stumped at this for a week. Thanks
I've tried this.IP, myjunk.IP, this,myjunk.IP. myjunk['IP']. Nothing returns. And when I do myjunk.IP I get "cant read from undefined"
One way to do this is to create a separate component:
const JunkButton = ({junk}) => (
<div className='plc-container' key={key} onClick={() => ReadStuff(junk)}>
<h1>ID:{junk['name']}</h1>
<h1>IP:{junk['IP']}</h1>
</div>
)
Now your map() looks like:
{Object.keys(myjunk).map((key) =>{ <JunkButton junk={ myjunk[key] }/> }
And ReadStuff becomes:
const ReadStuff = (junk) => { console.log(junk) }
Notice how in React we explicitly pass things around as props or function parameters.
first you need to pass myjuck to function and then console it like this:
{Object.keys(myjunk).map((key) =>{
return (
// sending myjuck to function whatever that is
<div className='plc-container' key={key} onClick={() => ReadStuff(myjunk)}>
<h1>ID:{myjunk[key]['name']}</h1>
<h1>IP:{myjunk[key]['IP']}</h1>
</div>
)
ReadStuff function
const ReadStuff = (myjunk) => { console.log(tmyjunk) }

how to return result from a function to component in ReactJS

I am trying to return the value of a function to the component in reactjs. The console.log within the function is getting displayed but the result is not getting returned. I am having trouble in this scenario everytime. Can any one please help me out.
Below is my code. Am unable to display the Waveform tag that is supposed to be returned from the function encodedAudioFilename()
const PopUpModal = props => {
.....
some code
.....
function encodedAudioFilename(){
const regex = /(?<=recordings\/).+/gm;
let m;
while ((m = regex.exec(audioLocation)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
console.log("https://d30pkmxa7non58.cloudfront.net/"+encodeURIComponent(match));
return <Waveform src={"https://d30pkmxa7non58.cloudfront.net/"+encodeURIComponent(match) }/>
});
}
}
return (
<ModalBody>
<div className="wave-player">
{encodedAudioFilename()}
</div>
</ModalBody>
)
};
export default PopUpModal;
Your function actually doesn't return anything
Try below code
function encodedAudioFilename(){
const regex = /(?<=recordings\/).+/gm;
let m;
let ar = [];
while ((m = regex.exec(audioLocation)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
// The result can be accessed through the `m`-variable.
arr = m.map((match, groupIndex) => {
console.log("https://d30pkmxa7non58.cloudfront.net/"+encodeURIComponent(match));
return <Waveform key={groupIndex} src={"https://d30pkmxa7non58.cloudfront.net/"+encodeURIComponent(match) }/>
});
arr = [...ar, ...arr];
}
return ar;
}

Cannot read property function of null

Hello I'm trying to test a function from a function but tells me this error.
TypeError: Cannot read property 'getNextServiceIconStyle' of null
Code
function IssueNextServiceIcon ({ nextService, intl }) {
return (
<div styles[getNextServiceIconStyle(nextService.approaching, nextService.overDue)])}>
<NextServiceIcon className={styles['icon']} />
</div>
)
function getNextServiceIconStyle (approaching, overDue) {
if (overDue) {
return 'next-service-overdue'
}
else if (approaching) {
return 'next-service-approaching'
}
return ''
}
}
Test
test('should', () => {
const wrapper = shallow(<IssueNextServiceIcon {...mockPropsForComponent} />)
const instance = wrapper.instance()
const expectedResult = 'next-service-overdue'
expect(instance.getNextServiceIconStyle(true, false)).toEqual(expectedResult)
})
Any suggestion for the test?
There a few syntax errors and unclosed braces, but if I understood your intent correctly, you'd do smth like this:
function IssueNextServiceIcon({ nextService, intl }) {
function getNextServiceIconStyle(approaching, overDue) {
if (overDue) {
return "next-service-overdue";
} else if (approaching) {
return "next-service-approaching";
}
return "";
}
const styleKey = getNextServiceIconStyle(
nextService.approaching,
nextService.overDue
);
return (
// Or if you need to pass className: className={styles[styleKey]}
<div styles={styles[styleKey]}>
<NextServiceIcon className={styles["icon"]} />
</div>
);
}
Regarding the test, you cannot use wrapper.instance() because this is not a class component. What you could do is to render your component and check that it has proper styles applied:
test('it should have correct styling', () => {
const wrapper = shallow(<IssueNextServiceIcon {...mockPropsForComponent} />)
expect(component.find('NextServiceIcon').prop('style')).toHaveProperty('color', 'red') // test for the actual css you have
})

State is not displayed after setting it in ReactJS

I am receiving some data as props and on click I am trying to display next items from array. In render I'm calling {this.dropdown()} which triggers folowing and display data succedsfully:
dropdown = () => {
var dropdown = undefined
if(this.props.catList){
const cat = this.props.catList
const list = JSON.stringify(this.props.catList)
if(list.length > 0){
dropdown = <div><p onClick={() =>{this.subCat()}}>{cat.title}</p>{this.state.firstSubCat}</div>
}
}
return dropdown
}
Next, when I click on item, sub categories is displayed with no issues and generates place where to display state for next function {this.state['sub'+cat.id]} :
subCat = () => {
let subCat = []
this.props.catList.children.map(cat => {
subCat.push(<div key={cat.id}><p key={cat.id} onClick={() =>{this.searchSubCat(cat.id)}}>{cat.title}</p>{this.state['sub'+cat.id]}</div>)
})
this.setState({firstSubCat: subCat})
}
Next two function is for loop through rest of array to display next items on click. (Please note that I did not use it from beginning because first line of data is not objects but contains 'children' as array so now i can use these two functions):
find = (array, id) => {
// Loop the entries at this level
for (const entry of array) {
// If we found it, return it
if (entry.id === id) {
return entry;
}
// If not but there's a type array, recursively search it
if (Array.isArray(entry.type)) {
const found = find(entry.type, id);
if (found) {
// Recursive search found it, return it
return found;
}
}
}
return undefined
}
searchSubCat = (id) => {
let subCat = []
const children = this.find(this.props.catList.children, id)
children.children.map(cat => {
subCat.push(<div key={cat.id}><p key={cat.id} onClick={() =>{this.searchSubCat(cat.id)}}>{cat.title}</p>{this.state['sub'+cat.id]}</div>)
})
this.setState({['sub' + id]: subCat})
}
So far there is no errors poping up but in generated place state is not being displayed. When generating place ( with this: {this.state['sub'+cat.id]} ) where to display state I pass its id to next step to set state with same id so state should be displayed there but nothing. If anybody can see where is issue could please respond could help me here out would be great ! Thanks.
Full code for component as requested in comment:
import React, {Component} from 'react';
class SearchResult extends Component {
constructor( props ){
super( props );
this.state = {
}
}
find = (array, id) => {
// Loop the entries at this level
for (const entry of array) {
// If we found it, return it
if (entry.id === id) {
return entry;
}
// If not but there's a type array, recursively search it
if (Array.isArray(entry.type)) {
const found = find(entry.type, id);
if (found) {
// Recursive search found it, return it
return found;
}
}
}
return undefined
}
searchSubCat = (id) => {
let subCat = []
const subId = 'sub' + id
console.log(subId)
const children = this.find(this.props.catList.children, id)
children.children.map(cat => {
subCat.push(<div key={cat.id}><p key={cat.id} onClick={() =>{this.searchSubCat(cat.id)}}>{cat.title}</p>{this.state['sub'+cat.id]}</div>)
})
this.setState({['sub' + id]: subCat})
}
subCat = () => {
let subCat = []
this.props.catList.children.map(cat => {
subCat.push(<div key={cat.id}><p key={cat.id} onClick={() =>{this.searchSubCat(cat.id)}}>{cat.title}</p>{this.state['sub'+cat.id]}</div>)
console.log('sub--'+cat.id)
})
this.setState({firstSubCat: subCat})
}
dropdown = () => {
var dropdown = undefined
if(this.props.catList){
const cat = this.props.catList
const list = JSON.stringify(this.props.catList)
if(list.length > 0){
dropdown = <div><p onClick={() =>{this.subCat()}}>{cat.title}</p>{this.state.firstSubCat}</div>
}
}
return dropdown
}
render() {
return (
<div>
{this.dropdown()}
</div>
)
}
}
export default SearchResult;
UPDATED:
I receive array from server with Redux which I send to my first component where I use map() method to find 1st level of array and send it to component with its childrens as props(catList). Cant really copy and paste catList prop value here so here is array, how i pass it and IMG of console.log(this.props.catList) :
Array:
[{"id":1,"title":"Electronics","path":"Electronics","children":[{"id":2,"title":"Accessories","children":[{"id":6,"title":"Portable Power Banks","children":[]},{"id":7,"title":"Charging Cables","children":[]},{"id":9,"title":"Batteries","children":[{"id":10,"title":"Disposable","children":[]},{"id":19,"title":"Rechargable","children":[]}]}]},{"id":3,"title":"Computers","children":[{"id":4,"title":"Components","children":[{"id":5,"title":"Laptops","children":[]}]}]}]},{"id":2,"title":"Accessories","path":"Electronics->Accessories","children":[{"id":6,"title":"Portable Power Banks","children":[]},{"id":7,"title":"Charging Cables","children":[]},{"id":9,"title":"Batteries","children":[{"id":10,"title":"Disposable","children":[]},{"id":19,"title":"Rechargable","children":[]}]}]},{"id":6,"title":"Portable Power Banks","path":"Electronics->Accessories->Portable Power Banks","children":null},{"id":7,"title":"Charging Cables","path":"Electronics->Accessories->Charging Cables","children":null},{"id":9,"title":"Batteries","path":"Electronics->Accessories->Batteries","children":[{"id":10,"title":"Disposable","children":[]},{"id":19,"title":"Rechargable","children":[]}]},{"id":10,"title":"Disposable","path":"Electronics->Accessories->Batteries->Disposable","children":null},{"id":19,"title":"Rechargable","path":"Electronics->Accessories->Batteries->Rechargable","children":null},{"id":3,"title":"Computers","path":"Electronics->Accessories->Computers","children":[{"id":4,"title":"Components","children":[{"id":5,"title":"Laptops","children":[]}]}]},{"id":4,"title":"Components","path":"Electronics->Accessories->Computers->Components","children":[{"id":5,"title":"Laptops","children":[]}]},{"id":5,"title":"Laptops","path":"Electronics->Accessories->Computers->Components->Laptops","children":null},{"id":11,"title":"Cars","path":"Cars","children":[{"id":12,"title":"Electronics","children":[{"id":13,"title":"Accessories","children":[{"id":14,"title":"Chargers","children":[]}]}]}]},{"id":12,"title":"Electronics","path":"Cars->Electronics","children":[{"id":13,"title":"Accessories","children":[{"id":14,"title":"Chargers","children":[]}]}]},{"id":13,"title":"Accessories","path":"Cars->Electronics->Accessories","children":[{"id":14,"title":"Chargers","children":[]}]},{"id":14,"title":"Chargers","path":"Cars->Electronics->Accessories->Chargers","children":null},{"id":15,"title":"DIY","path":"DIY","children":[{"id":16,"title":"Power Tools","children":[{"id":17,"title":"Accessories","children":[{"id":18,"title":"Batteries","children":[]}]}]}]},{"id":16,"title":"Power Tools","path":"DIY->Power Tools","children":[{"id":17,"title":"Accessories","children":[{"id":18,"title":"Batteries","children":[]}]}]},{"id":17,"title":"Accessories","path":"DIY->Power Tools->Accessories","children":[{"id":18,"title":"Batteries","children":[]}]},{"id":18,"title":"Batteries","path":"DIY->Power Tools->Accessories->Batteries","children":null}]
and here i use map() method from where prop catList is passed to component:
this.props.searchRes.map(cat => {
if(!cat.path.includes('->')){
categories.push(<SearchResult filtered={false} title={cat.title} id={cat.id} catList={cat} key={cat.id}/>)
}
})

Iterating through array gives .map is not a function error in reactjs

I want to iterate through each element in the array and display it in the breadcrumb navigation.
What i am trying to do?
from a particular path or location say /list/item_id and if the item has certain information my breadcrumb navigation should change to the hierarchy of information.
For example, say i have the information of the item stored in item_information...and it is array of objects as below,
const item_information = [
{
name: "c_name",
},
{
name: "a_name",
},
{
name: "name",
}
I want to retreive only the name of each object and store it in variable display and want to display that in the breadcrumb navigation....so to loop through each name value from the variable display i use .map function. In doing so , i get an error .map is not a function.
Below is the code,
class Crumb extends React.PureComponent {
render = () => {
const link = this.props.link;
let display;
let match;
let after_link;
if (link === '/') {
display = 'Home';
} else if (match = link.match(/^\/list\/new$/)) {
display = 'new item';
} else if (match = link.match(/^\/list\/([^/]+)$/))
if (this.props.item_information > 0) {
display = this.props.item_information.map((el) => {
return el.name;
});
} else {
const model_id = match[1];
const model = this.props.models && this.props.models.find(model
=> '' + model.id === model_id);
display = itemname;
after_link = 'after_link';
}
}
//last part of the link
if (!display) {
const parts = link.split('/');
display = parts[parts.length - 1];
}
return (
<div>
{Array.isArray(display) && display.map((display) => {
return (
<div className="crumb">
<Link to={link}>{display}</Link>
</div>
);
})}
<div className="crumb">
<Link to={link}>{display}</Link>
</div>
{after_link}</div>
);
};
}
class Breadcrumb extends React.PureComponent {
render = () => {
const path = this.props.location.pathname;
const crumbs = [];
path.split('/').slice(1).forEach((part, index, parts) => {
crumbs.push('/' + parts.slice(0, index + 1).join('/'));
});
return (
<div className="breadcrumb">
{crumbs.map((link, i) => {
return (
<Fragment key={link}>
<Crumb
item_information={this.props.item_information}/>
</Fragment>);
})}
</div>
);
};
}
Could someone help me in getting rid off the error .map is not a function. thanks.

Resources