Santosh Prasad
Santosh Prasad

Reputation: 59

Dynamic Background Image React

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>

Upvotes: 3

Views: 22594

Answers (6)

A. Christopher
A. Christopher

Reputation: 1

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>

Upvotes: 0

Desarrollalab
Desarrollalab

Reputation: 397

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;

Upvotes: 0

Santosh Prasad
Santosh Prasad

Reputation: 59

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

Upvotes: 0

Steve Holgado
Steve Holgado

Reputation: 12071

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.

Upvotes: 3

Sivcan Singh
Sivcan Singh

Reputation: 1892

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>

Upvotes: 2

stef
stef

Reputation: 14268

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.

Upvotes: 1

Related Questions