Universal: [innerHTML] broken

Created on 27 Sep 2016  路  17Comments  路  Source: angular/universal

Note: for support questions, please use one of these channels: https://github.com/angular/universal/blob/master/CONTRIBUTING.md#question. This repository's issues are reserved for feature requests and bug reports. Also, Preboot has moved to https://github.com/angular/preboot - please make preboot-related issues there.

  • I'm submitting a ...
  • [x] bug report
  • What modules are related to this Issue?
  • [x] universal
  • What is the current behavior?

[innerHTML] works fine on browser side, but does not render anything on the server.

  • If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem by creating a github repo.

Only changes to app.ts compared to universal-starter repo

@Component({
  selector: 'home',
  template: '<h2 [innerHTML]="foo"></h2>'
})
export class Home {

  foo: any;

  constructor(private sanitizer: Sanitizer) {
    this.foo = this.sanitizer.sanitize(SecurityContext.HTML, 'Foobar');
  }
}
  • What is the expected behavior?

The universal app should render innerHTML. Instead, the h2 element is empty:

<app>
  <p>Hello Angular Universal App</p>
  <router-outlet></router-outlet>
  <home>
    <h2></h2>
  </home>
</app>

After browser has bootstrapped, the DOM is as follows:

<app>
  <p>Hello Angular Universal App</p>
  <router-outlet></router-outlet>
  <home>
    <h2>Foobar</h2>
  </home>
</app>
  • Please tell us about your environment:
  • Angular version: 2.0.0
  • angular-universal version: 2.0.11
  • Language: TypeScript 2.0.0
  • OS: Mac OS X
  • Platform: NodeJs
required

Most helpful comment

We were all just talking about this one, this was fixed in the past, but it looks like it _may_ be an Angular Core issue that's causing it. Jeff was saying unfortunately most of the Core team is also @ the Connect conference so it may not be resolved until next week. Thanks for reporting the issue though!

All 17 comments

We were all just talking about this one, this was fixed in the past, but it looks like it _may_ be an Angular Core issue that's causing it. Jeff was saying unfortunately most of the Core team is also @ the Connect conference so it may not be resolved until next week. Thanks for reporting the issue though!

Since upgrading from RC4, I also see the innerHTML / SafeHtml issue. SafeResourceUrl in a <link> attr.href is not working for me either. May need to check all DomSanitizer functions.

@MarkPieszak I am also facing the same problem with innerHTML
I am using 2.0.0 version .

@jeffbcross can you take a look into this? It was working before and something in core may have changed.

see PR https://github.com/angular/universal/pull/570 the change was parse5 2.x.x

can you try angular2-universal 2.1.0-rc.1 where this is merged. thanks!

Thanks, we'll try it!

I was having an issue with [innerHTML] not rendering on the server and can confirm it's fixed in 2.1.0-rc.1

Was this ever sorted?
I'm using @angular 4.3.3 and @angular/cli 1.3.0-rc.5 and innerHtml is not rendered

In some cases if I wrap the parent element in an ngIf check, it fixes the issue.

@patrickmichalina what is your ngIf check using? I've tried a boolean that changes once the http request for the page has finished but that doesn't work either.

Paste some sample code and I might be able to give you pointers? I'm still not sure why this issue is happening, but since I've been able to mitigate it, I haven't spent too much time worrying about it at the moment.

This is my template

  <div *ngIf="loaded">
    <span [innerHtml]="page.body"></span>
  </div>

and component is

export class PageComponent implements OnInit {
  public page: any;
  public loaded: boolean = false;
  constructor(private api: ApiService, private route: ActivatedRoute) {
    this.api.endpoint = 'page';
  }

  ngOnInit() {
    this.api
      .findOne(this.route.snapshot.url[0].path, {
        $select: {
          title: 1,
          body: 1,
          seo: 1
        }
      })
      .subscribe(resp => {
        this.page = resp;
        this.loaded = true;
      });
  }
}

@dottodot Strange that it is not working..... but you can try this, moving your http request into the constructor, but am not so sure it will fix it:

export class PageComponent implements OnInit {
  public page$ = this.api
      .findOne(this.route.snapshot.url[0].path, {
        $select: {
          title: 1,
          body: 1,
          seo: 1
        }
      });
  constructor(private api: ApiService, private route: ActivatedRoute) {
    this.api.endpoint = 'page';
  }
}

<div *ngIf="page$ | async as page">
    <span [innerHtml]="page.body"></span>
 </div>

I've got to the bottom of it and my original setup works as well.

There was a error server side and because some of the page was rendering I was assuming there shouldn't be a reason for this not to render as well. Maybe [innerHtml] is a bit more sensitive to this sort of thing.

@patrickmichalina this works great. thank you

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

daright picture daright  路  6Comments

inorganik picture inorganik  路  4Comments

jeffwhelpley picture jeffwhelpley  路  4Comments

flexchintoo picture flexchintoo  路  5Comments

ahmedwerpx picture ahmedwerpx  路  4Comments