45

I have been struggling to figure out the best way to dynamically change the background-image attribute in a number of Angular 2 components.

In the following example, I am attempting to set the background-image of a div to an @Input value using [ngStyle] directive:

import {Component, Input} from '@angular/core';
import { User } from '../models';

// exporting type aliases to enforce better type safety (https://github.com/ngrx/example-app)
export type UserInput = User;

@Component({
  selector: 'profile-sidenav',
  styles: [ `
    .profile-image {
      background-repeat: no-repeat;
      background-position: 50%;
      border-radius: 50%;
      width: 100px;
      height: 100px;
    }
  `],
  template: `  
    <div class="profile-image" [ngStyle]="{ 'background-image': url({{image}})">
    <h3>{{ username }}</h3>
  `
})

export class ProfileSidenav {
  @Input() user: UserInput;
  blankImage: string = '../assets/.../camera.png';

  // utilizing "getters" to keep templates clean in 'dumb' components (https://github.com/ngrx/example-app) 
  get username() {
    return this.user.username;
  }
  get image() {
    if (!this.user.image) { return this.cameraImage;
    } else { return this.user.image; }
  }

I don't think the issue is with the observable, since username displays and doing something like <img *ngIf="image" src="{{ image }}"> renders the image. I have to access the background-image attribute because apparently that is the best way to make a circular image, but in general would like to know how to do this.

EDIT:

My original [ngStyle] declaration had unnecessary curly brackets (ngStyle is a directive that can take a variable), and was missing string tags around url() and image. The correct way is (as answered below) is:

<div class="profile-image" [ngStyle]="{'background-image': 'url(' + image + ')'}"></div>`.

As stated in the original edit, a solution can also be achieved with the Renderer class in Angular 2. I have yet to do it but think there should be a way with setElementStylesor something like that. I will try to post an example but would love if someone else showed me (and others) how to for the time being.

0xPingo
  • 1,727
  • 2
  • 16
  • 40

5 Answers5

81

I think that you should use something like that:

<div class="profile-image"
     [ngStyle]="{ 'background-image': 'url(' + image + ')'}">

where image is a property of your component.

See this question:

Community
  • 1
  • 1
Thierry Templier
  • 191,422
  • 38
  • 386
  • 349
  • Thanks for the response! I tried your suggestion (with an extra curly bracket at the end, and the image didn't render :/. Also tried this and had no luck: `
    `
    – 0xPingo Jun 01 '16 at 19:43
  • Does it have to do with how I have `image` defined? Your example (plus the extra curly bracket) does not cause any errors, but the image still does not render :/. I tried putting `blankImage` in there as well (defined locally instead of through an observable), but had the same result. @Thierry – 0xPingo Jun 01 '16 at 20:04
  • You're welcome! Is the `background-image` style applied to your element? You can see this within the Elements tab of Dev tools... – Thierry Templier Jun 01 '16 at 20:05
  • No, the style is not getting applied @Thierry Templier – 0xPingo Jun 01 '16 at 20:06
  • (But is applied when I defined it in the .profile-image css up top) – 0xPingo Jun 01 '16 at 20:07
  • 2
    Nvm, got it to work. The `blankImage` I was referencing had some blank spaces in the path, so that was causing the issue. – 0xPingo Jun 01 '16 at 20:25
  • 1
    tried editing your response to add the extra curly bracket but it wasn't 6 characters (minimum required). Please edit so I can accept! Thanks ! – 0xPingo Jun 01 '16 at 20:27
  • 1
    See also http://stackoverflow.com/questions/37076867/in-rc-1-some-styles-cant-be-added-using-binding-syntax/37233523#37233523 – Günter Zöchbauer Jun 02 '16 at 05:15
38

You don't need to use NgStyle. You can also do this:

[style.background-image]="'url(' + image + ')'"

See more at How to add background-image using ngStyle (angular2)?

Tharindu Lakshan
  • 2,024
  • 2
  • 13
  • 37
redfox05
  • 2,754
  • 1
  • 29
  • 35
2

The main reason is simple, you declared a global variable as blankImage but in the template you called image instead of blankImage.

Your ts code variable blankImage

blankImage: string = '../assets/.../camera.png';

Your template code variable image

<div class="profile-image" [ngStyle]="{'background-image': 'url(' + image + ')'}"></div>
0

redfox05's answer works well since there is no space in the image URL, but by a bit change in code we can make it work again:

<div style.background-image="url('{{image}}')"></div>"
-3

that's wrong

I think you should add:

<div class="profile-image" [ngStyle]="{ 'backgroundImage': url({{image}})">

Regards

Amir.S
  • 640
  • 8
  • 13
  • 1
    the RHS part already contains an expression, and you are adding another expression {{image}} into that. This will trigger an error. – Joseph Jojo John Aug 12 '20 at 21:10