How do you use React collection attributes in inline styling? - reactjs

I'm attempting to set the background image for each item in a collection but I'm receiving a syntax error when attempting to access the model attribute. Can anyone help out?
You can assume the collection has been received.
class MyThing extends React.Component {
const collection = this.props.collection;
render () {
return (
<div>
{collection.models.toList().map((model,key) =>
<div className="post" key={model.id}>
<div className="graphic"
style={{background:"url(" + {model.img_url} + ")"}}>
</div>
</div>
)}
</div>
);
}
}
However, I'm receiving the following syntax error which implies I can't use the normal dot notation to access the attribute:
ERROR in ./MyThing.js
Module build failed: SyntaxError: Unexpected token, expected , (55:87)
53 | div className="post" key={model.id}>
> 55 | <div className="graphic" style={{background:"url(" + {model.img_url} + ")"}}></div>
| ^
What's the appropriate way of setting model attributes from a collection like this?
Any thoughts?

Try removing the curly brackets around model.img_url to get this:
<div className="graphic" style={{background:"url(" + model.img_url + ")"}}></div>

Related

React TypeError: x.filter is not a function

When I run tis code on localhost did not show any error
const displayProduct = product
.filter(prod =>
prod.category.includes(filters.category) &&
prod.brand.includes(filters.brand) &&
prod.type.includes(filters.type)
)
.filter((product)=>{
if (searchTerm == ""){
return product
}else if(product.productName.replaceAll(/\s/g,'').toLowerCase().includes(searchTerm.toLowerCase().replaceAll(/\s/g,''))){
return product
}
})
.slice(pagesVisited,pagesVisited + productPerPage)
.map(product => {
return(
<div className='imageContainer ' key={product.id}>
<img src={product.productImageOne?require(`../../Images/${product.productImageOne}`):null} className="image"/>
<div className='productName'>
<Link style={{ textDecoration:'none' }} to="/productsDetails" state={{ product:product }}>{product.productName?product.productName:null}</Link>
</div>
</div>
)
})
But when I host my website on a server it show "TypeError: x.filter is not a function"..
How do I solve it?
This occurs because product isn't defined yet.
In your local machine, product may be an array containing your data when React is processing the view because your server may be on you machine, but on your server, you may need to wait longer in order to make your HTTP request.
You can fix your error by replacing all your product. occurence by product?., such as:
const displayProduct = product
?.filter(prod =>
...
)
?.filter((product)=>{
...
})
?.slice(...)
?.map(...)
Plus, you may need to check product or displayProduct's value before, to add a loader or spinning stuff showing data's fetching.

when myItems is an empty array, it is saying 'myItem.map() is not a function'. how to solve?

When items are present in myItems state, the website is ok. but if there is no item, the website breaks.
const [myItems, setMyItems] = useState([]);
return (
<div className="container my-5">
<div className="row g-5">
{
myItems?.map(myItem => <MySingleItem key={myItem._id} myItem={myItem} handleItemDelete={handleItemDelete} />)
}
</div>
</div>
);
The issue is your myItems is actually receiving a value that is not an array type.
Doing
const myItems = 'b';
myItems.map((a) => a)
will give the same error Uncaught TypeError: myItems.map is not a function.
It's telling you .map is not a function because the data type of the value of myItems at that point in time is something else.
Check your usage of setMyItems in the rest of your component code or share the full code because I believe you're setting it as a non-array type by mistake.

Can't dynamically render reactjs elements using .map()

I am trying to dynamically render out ingredient/qty/measure using .map() in reactjs I am following a few tutorials online but unable to properly implement the code in my own code.
Here is the error I am currently getting:
react-dom.development.js:86 Warning: Functions are not valid as a React child.
This may happen if you return a Component instead of <Component /> from render.
Or maybe you meant to call this function rather than return it.
Here is the data I am trying to map over:
recipeIngredients: Array(2)
0: {name: 'lemon', quantity: '100', measure: 'g'}
1: {name: 'butter', quantity: '5', measure: 'cups'}
Here is my code:
import './IngredientsList.css'
let ingredientArray
function mapIngredients() {
ingredientArray.map((item) => (
<div className="ingredient-element">{item}</div>
))
}
function IngredientsList(props) {
console.log(props)
ingredientArray = props.recipeIngredients
return <div className="ingredient-list">{mapIngredients}</div>
}
export default IngredientsList
Basically, trying to render out the following set of divs (recipeIngredients.name has an additional class):
<div className="ingredient-list">
<div className="ingredient-element">recipeIngredients.quantity</div>
<div className="ingredient-element">recipeIngredients.measure</div>
<div className="ingredient-element ingredient-name">recipeIngredients.name</div>
</div>
I notice that the () are missing from the IngredientList function - VSCode keeps deleting them when I save the code so I can't manually add them...
You forgot to invoke the function. Here you're trying to render the function itself:
return <div className="ingredient-list">{mapIngredients}</div>
Instead, invoke the function and render its result:
return <div className="ingredient-list">{mapIngredients()}</div>
Additionally, the function currently doesn't return anything. Add a return statement:
function mapIngredients() {
return ingredientArray.map((item) => (
<div className="ingredient-element">{item}</div>
))
}
I'm seeing two issues here. First, you're not invoking the function(as you said that vs code is not letting you do that). The second is item is an object here. Try this instead:-
function IngredientsList(props) {
console.log(props)
ingredientArray = props.recipeIngredients || [];
return (
<div className="ingredient-list">
{
ingredientArray.map(item => (
<div className="ingredient-element">{item.name}</div>
))
}
</div>
)
}

rootInstance.findByType("input"); Giving Expected 1 but found 2 instances with node type : "undefined"

So I have a component that shows some text fields. One input, one select and based on the input the user uses on that select, (The value of the select) the third is shown or not.
Im trying to use React-Test-Renderer to test the first input field only, but Im getting the following Error:
Expected 1 but found 2 instances with node type: "undefined"
Here is the input field code:
<div>
<div className="container">
<h3 className="h3">Info</h3>
<div className="row">
<div className="col">
<label htmlFor="test">test:</label>
<input
id="myID"
value={aPropThatIsAnEmptyString}
type="text"
className={`form-control form-control-sm ${style.fieldsGap}`}
onChange={e => setTest(e.target.value)}
placeholder="test"
/>
</div>
<div className="col">
<label htmlFor="ddlType">test2:</label>
<select
id="SelectId"
Here is my test code:
it("test input field", () => {
const newProps = {
something: initialState,
dispatch: reducer
};
const component = TestRenderer.create(
<ContextBR.Provider value={{ ...newProps }}>
<ComponentWithTheFields/>
</ContextBR.Provider>
);
const rootInstance = component.root;
console.log(rootInstance);
const inputField = rootInstance.findByType("input");
inputField.props.onChange({ target: { value: "" } });
expect(inputField.props.value).toBe("");
inputField.props.onChange({ target: { value: "blue" } });
expect(inputField.props.value).toBe("blue");
});
IF you're wondering what ContextBR.Provider is, we used context instead of redux.
My error message:
Expected 1 but found 2 instances with node type: "undefined"
29 | const rootInstance = component.root;
30 | console.log(rootInstance);
> 31 | const inputField= rootInstance.findByType("input");
| ^
32 |
33 | inputField.props.onChange({ target: { value: "" } });
34 | expect(inputField.props.value).toBe("");
I tried ad first without the <ContextBr.Provider wrapping but that gave me Dispatch is null or undefined. Which is probably because I didnt send the context too and the component uses it.
I was expecting it to find the input, and assert if its value is at the one I sent in, "". After that I was aiming at adding duplicate code just instead of sending in "" rather send in "blue " (just as an example) then assert on that.
Im trying to test user experience. That he can type on it and that it shows what he's typing.
From the documentation
testInstance.findByType()
Find a single descendant test instance with the provided type. If there is not exactly one test instance with the provided type, it will throw an error.
My guess is that you have more than one input field hidden in your component, causing findByType() to throw an error.
You can pick one of the input fields by using
rootInstance.findAllByType("input")[index]
Note: I'm not sure why React says the type is undefined, but findAllByType() still works for me.

Cannot read property 'lng' of undefined

I am using customer marker in google maps using ng-map.min.js
I am change the position of the custom marker, but it is showing the following error :
Uncaught TypeError: Cannot read property 'lng' of undefined
at a.setPosition (ng-map.min.js:25)
at a.draw (ng-map.min.js:25)
at a.Mz (overlay.js:1)
at js?key=xxx&callback=lazyLoadCallback:138
The code i write for custom marker is :
in html file :
==============
<custom-marker ng-repeat="p in page.watchpath track by $index" position="{{p.Location.position}}">
<div>
<img src="{{p.ImagePath ? page.serviceBasePath + p.ImagePath.substr(2) : page.serviceBasePath + 'Images/avatar.jpg'}}" style="border-radius: 50%; height:40px;width:40px;" />
</div>
</custom-marker>
in js file :
============
page.watchpath[deviceindex] = { position: device.Location.position, ImagePath: imagePath };
But When i am using for marker tag it is not showing any error :
<marker ng-repeat="p in page.watchpath track by $index" position="{{p.position}}"></marker>
When i am using for custom-marker tag it showing error message
How to rectify this error ?
Please help me ...?
What does the following function returns in your code?
device.Location.position
The model which you pass in your view (p.position) should be a one dimension array:
p.position = [0,0]
The first index is 'lat' the second is 'lng.

Resources