Toggle display block on element in multiple views


#1

I got a notification element in every view which has display: none. I want it to show when my get request returns an error. Now I can’t use getElementById because of how Ionic works. So I found that I need to use ViewChild but i’m unsure on how to use it with style properties.

My current error:

Cannot set property 'display' of undefined

HTML

<div class="notification" #showNotification>
        <img src="{{ notification?.image }}">
        <span>{{ notification?.title }}</span>
        {{ notification?.content }}
 </div>

Controller

 @ViewChild('showNotification') showNotification;

    constructor(public navCtrl: NavController, public navParams: NavParams, public http: Http, public globalProvider: GlobalProvider, private socialSharing: SocialSharing) {
        this.postID = navParams.get('postID');

        this.http.get('https:/...').map(res => res.json()).subscribe(
            data => {
                this.post = data;
                this.postURL = data.link;
            },
            err => {
                this.showNotification.style.display = 'block';
                this.notification = globalProvider.notification['internal'];
                console.log('Error ' + err.status + ' | ' + JSON.parse(err._body).message);
            }
        );

If I do this instead it will just stay hidden.

                this.showNotification.style = 'display:block !important';

#2

Ow I found it. I needed to add nativeElement.

this.showNotification.nativeElement.style = 'display:block';

#3

A much more idiomatic way of doing this is:

<div *ngIf="notification">
  <img [src]="notification.image">
  <span>{{notification.title}}</span>
  {{notification.content}}
</div>

By guarding with *ngIf you do not need the Elvis operator. This assumes that you want this to show if notification is truthy. If you would like to use some other boolean property, that would work fine as well. If for whatever reason you insist on the element being in the DOM even when not being shown, instead of using ngIf you can bind the [hidden] attribute to a boolean. You do not need @ViewChild or any direct DOM manipulation.


#4

Ah that works better, thanks :smiley: What is the difference between using [src] and src={{ }}?


#5

Short answer: the first one is better.

Longer answer: the second one only works for strings. If all you’re dealing with is strings, there’s no difference between the two.