Dynamic Background Image React - html

I am trying to select backgroundImage dynamically based on value of item.imageLinks.smallThumbnail.
If the array returned by my API has a smallThumbnail URL then I want to use that as the backgroundImage or use a local default backgroundImage of book.png inside ../public.
Below is my code, but it's not working when item.imageLinks.smallThumbnail is undefined and it's not using the alternate book.png but giving me the error:
Type Eror: Cannot Read 'smallThumbnail of undefined
Please help.
Thanks
return(
<ol className="books-grid">
{book.map( (item) => (
<li key={item.id}>
<div className="book">
{item.shelf && (
<div className="book-top">
<div
className="book-cover"
style={{ width: 128, height: 193, backgroundImage: `url({${item.imageLinks.smallThumbnail} || ../public/book.png } )` }}></div>

If imageLinks is undefined then it is not an object so you won’t be able to use dot syntax, hence the error trying to get the smallThumbnail property.
Try this instead:
<div
className="book-cover"
style={{
width: 128,
height: 193,
backgroundImage: `url(${(item.imageLinks && item.imageLinks.smallThumbnail) || "../public/book.png"})`
}}
></div>
... so you are checking for imageLinks first.

Since your imageLinks itself is not a property you can handle this like so:
let imageUrl = item.imageLinks ? item.imageLinks.smallThumbnail : '../public/book.png';
return(
<ol className="books-grid">
{book.map( (item) => (
<li key={item.id}>
<div className="book">
{item.shelf && (
<div className="book-top">
<div
className="book-cover"
style={{ width: 128, height: 193, backgroundImage: `url(${imageUrl})` }}></div>

in your code you need to handle the situation where item.imageLinks is not defined, so the problem is with this line:
`url({${item.imageLinks.smallThumbnail} || ../public/book.png })`
Here, if imageLinks is undefined, the line will error out.
Instead you could use the ternary operator like this:
`url({${(item && item.imageLinks && item.imageLinks.smallThumbnail) ? item.imageLinks.smallThumbnail : `../public/book.png`} })`
Although this is very hard to read.
I'd consider refactoring this so that you have an array of objects at the top of your render method, where you store the image and image url for each item and then iterate over that in your render method.

This is now solved, Below is the code that worked.
return(
<ol className="books-grid">
{book.map( (item) => (
<li key={item.id}>
<div className="book">
{item.shelf && (
<div className="book-top">
<div className="book-cover" style={{ width: 128, height: 193, backgroundImage: `url(${(item.imageLinks && item.imageLinks.smallThumbnail) || "book.jpg"})` }}></div>
One trick that i learned here is using && to check for undefined otherwise JS will complain of error.
Thanks Everyone

This is an exaple if you're using react js
import React, { Component, Fragment } from 'react'
import { Link } from 'react-router-dom'
const Post = (data) => {
return (
<div
style={{
backgroundImage: `linear-gradient(
325deg,
rgba(0, 36, 51, 1) 0%,
rgba(98, 218, 255, 0.164) 100%
),url(${(data.img)})`
}} className="cardService">
<div>
<h1 className='serviceTitle'>{data.name}</h1>
<h6 className='serviceDescription'>{data.description}</h6>
</div>
</div>
</Fragment>
)
}
export default Post;

Below is an example of code that works for me, adding double quote around it worked
let imageUrl = item.imageLinks ? item.imageLinks.smallThumbnail : '../public/book.png';
return(
<div className="book-cover" style={{ width: 128, height: 193, backgroundImage: `url("${imageUrl}")` }}></div>

Related

How to dynamically change the css style of a particular item inside a map function

I currently have two map functions to render a board for a chess game like this:
<div className='board'>
{rows.map((item) => (
<div key={item} className='row'>
{item.map((square) => (
# The square <div> => <div key={square[0]} className='square' onClick={() => {
board.select !== null &&
checkColour(board.select[1]) !== checkColour(square[1]) && dispatch(move(square))
}}>
{isNaN(square[1]) && <img src={square[1]} alt={square[1]}
onClick={() => { board.turns === checkColour(square[1]) && dispatch(select(square)) }}
className={board.select === square ? 'piece-selected' : 'piece'} />}
</div>
))}
</div>
))}
</div>
Now, I want to change the css style of certain squares <div> after I selected a pawn piece in order to forecast a shadow for showing the possible moves. I want to know is it possible to access the css style of that particular square <div> using the key of that <div>?
Feel free the drop a comment below if you have any insight or idea. Let me know if you want more info. Much appreciated.

Uncaught TypeError: target.className.indexOf is not a function at HTMLDocument.triggerTranslation

Why i got this error? I wanna create menu for mobile devises, but i do not have enough experience for this, so i decided to try to do something like this:
function Header() {
const [menuIsClicked, setmenuIsClicked] = useState(false)
const auth = useContext(AuthContext)
const clickMenuHandler = (menuIsClicked) => {
if (menuIsClicked) {
return setmenuIsClicked(false)
}
return setmenuIsClicked(true)
}
return (
<>
<header className="hd-home">
<MenuForMobiles menuIsClicked={menuIsClicked} clickMenuHandler={clickMenuHandler} />
<div className="nav-link1">
Home
About
Donate
</div>
<div className="nav-link2">
Profile
<a className="nv-btn"
href=""
>Exit</a>
</div>
</header>
<a href="">
<WeeklyNews />
</a>
</>
)
}
function MenuForMobiles(menuIsClicked, clickMenuHandler) {
if (menuIsClicked) {
return (
<div className="m-o"
style={{
backgroundColor: 'pink',
width: '100vw !important',
height: '100vh !important',
}}>
<i onClick={() => clickMenuHandler}>
<FontAwesomeIcon icon={faListUl} />
</i>
</div >
)
}
return (
<div className="m-o">
<FontAwesomeIcon icon={faListUl} />
</div>
)
}
I think that a problem is on my clickMenuHandler function.
Thx for any advices and help. By the way, as you can see, i am new on react :)
First of all, this error can be caused by plugins in your browser. In my case it was google translator. I just removed it cuz i don't use it, but will be better if you'll try to ignore/catch this error.
Second, you can use source code like this to make things like DropDownButton
https://www.telerik.com/kendo-react-ui/components/buttons/dropdownbutton/

When I try to change colour depends on the count it show's the error TypeError: Cannot read property 'style' of null

In the below I would like to change the colour to black if the count is === 0
if(Count === 0){
document.getElementById('value').style.color = 'black';
}
return(
<div className='container_new'>
<h1>Counter</h1>
<span id='value'>{Count}</span>
<div>
<button className="btn decrease" onClick={handleDecrement} >decrease</button>
<button className="btn reset" style={{color: 'black'}} onClick={() => handleReset()}>reset</button>
<button className="btn increase" onClick={() => handleIncrement()}>increase</button>
</div>
</div>
)
You can achieve what you wanted this way.
return(
<div className='container_new'>
<h1>Counter</h1>
<span id='value' style={{ color: Count === 0 ? 'black' : 'white' }}>{Count}</span>
<div>
<button className="btn decrease" onClick={handleDecrement} >decrease</button>
<button className="btn reset" style={{color: 'black'}} onClick={() => handleReset()}>reset</button>
<button className="btn increase" onClick={() => handleIncrement()}>increase</button>
</div>
</div>
)
in react.js i would approach this differently because it render and change the DOM (html tree)
so maybe instead of using
**document.getElementById('value').style.color = 'black';**
make a class in CSS and change the className based on the Count
like this
css class
.black {
color : black;
}
.green {
color : green;
}
react.js code
<span id='value' className={Count === 0 ? "black" : "green" } >{Count}</span> // tell me if this line is understandable
replace this line with your line and see if is working !
it would help me understand better if you show us the the handle increment function handle reset and handle decrement :)
Create a local state for the count and track the update. Based on the count value in the state, update the template style.
const [count, setCount] = useState(0);
return(
<div className='container_new'>
<h1>Counter</h1>
<span id='value'>{count}</span>
<div>
<button className="btn decrease" onClick={handleDecrement} >decrease</button>
<button className="btn reset" style={{color: (count === 0 ? 'black': 'green')}}
onClick={() => setCount(0)}>reset</button>
<button className="btn increase" onClick={() => handleIncrement()}>increase</button>
</div>
</div>
I believe, your react state is state = { Count: 0 }, If yes, when react starts initial rendering, you're trying to get the element by id, at this time, there no element(not rendered) with <span id='value'>{Count}</span> which returns null. That's why you're getting this error Cannot read property 'style' of null.
But, you can simply use following solution
<span id="value" style={{ color: Count === 0 ? 'black' : 'green' }}>{Count}</span>

Using ngClass 'Missing expected }' error being received

I am trying to conditionally add a class to a list item (through a child components selector), depending on the images width size. The width size is hard coded when the new image item is created in another component.
I keep receiving the error message :
'Missing expected }' in my gallery-list.component.html file.
I can't see that I am missing } anywhere. Can anyone help?
Here is the gallery-list html code:
<ul class="container">
<li class="item-list-container" data-masonry='{ "itemSelector": ".grid-item", "columnWidth": 160 }'><app-image-item
class="image-item"
*ngFor="let imageEl of images;"
[image]="imageEl"
[ngClass] ="{
'widthOne': imageEl.widthSize === 50px,
'widthTwo': imageEl.widthSize === 100px,
'widthThree': imageEl.widthSize === 150px,
'widthFour': imageEl.widthSize === 200px,
}"
(click)="onImageSelect(imageEl.id)"
></app-image-item>
</li>
</ul>
That's not a correct syntax. Take a look at this similar demo. Try
<ul class="container">
<li class="item-list-container" data-masonry='{ "itemSelector": ".grid-item", "columnWidth": 160 }'><app-image-item
class="image-item"
*ngFor="let imageEl of images;"
[image]="imageEl"
[ngClass] ="getClass(imageEl.widthSize)"
(click)="onImageSelect(imageEl.id)"
></app-image-item>
</li>
</ul>
in ts file:
getClass(widthSize): string{
if(widthSize === "50px") {
return "widthOne"
}
if(widthSize === "100px") {
return "widthTwo"
}
if(widthSize === "150px") {
return "widthThree"
}
if(widthSize === "200px") {
return "widthFour"
}
}
Note:
I would recommend you to add a property on images array deciding the class which has to be added, rather than using function call as I did using getClass(). Using function on HTML is a bad practice.
If the image is coming from some service, you can use .map and add className property on it.

How to wrap cover div inside reactjs fragments dynamically

I am trying to wrap html around inner div only when some condition is met. But when I run the script, it says Module build failed: SyntaxError Unexpected token. I tried to use conditional rendering.
return (
<Fragment>
<div>
{
(true) ? <div class="imghvr-wrapper"> : ''
}
<div class="imghvr">
<div class="imghvr-overlay imghvr-anim-none imghvr-anim-single">
</div>
{
(true) ? </div> : ''
}
</div>
</Fragment>
);
Like this:
const myComponent = () => {
const myCondition = true;
const child = (
<div className="imghvr">
<div className="imghvr-overlay imghvr-anim-none imghvr-anim-single" />
</div>
);
return (
myCondition ? <div className="imghvr-wrapper">{ child }</div> : child
);
};
You can't split tags like this: myCondition ? <div className="imghvr-wrapper"> : null you should always close your tags. For example that code is valid: (true) ? <div className="imghvr-wrapper"/> : '' because tag is closed