3

what I want to do exactly is to render text coming from the backend as a part of the angular template with full features like interpolations and directives (ngfor, if, switch).

Here is a brief example

template.component.ts

import { Component, OnInit } from '@angular/core';
import { MyService } from '../my.service';
@Component({
  selector: 'app-template',
  templateUrl: './template.component.html',
  styleUrls: ['./template.component.scss']
})
export class TemplateComponent implements OnInit {
  names: string[];
  template: string;
  constructor(
    private myService: MyService
  ) { }

  ngOnInit() {
      this.myService.getTemplate('page-name').subscribe(data => {
        // say data = <span *ngFor="let name of names">hello {{name}}</span>
        this.template = data;
      });
      this.myService.getNames().subscribe(data => {
        // say data = ['name 1', 'name 2', 'name 3']
        this.names = data;
      });
  }

}

template.component.html

<div [innerHTML]="sample"></div>

Current output

hello {{name}}

Desired output

hello name 1
hello name 2
hello name 3

here is the closest thing i found to what i need https://blog.angularindepth.com/here-is-what-you-need-to-know-about-dynamic-components-in-angular-ac1e96167f9e

Robert
  • 83
  • 1
  • 8
  • Could you please check [this link](https://stackoverflow.com/questions/51373442/how-to-make-popovers-placed-inside-a-innerhtml-attribute-work/51373689#51373689)? – Malindu Sandaruwan Jul 30 '18 at 13:36
  • @Katana24 i want it to work with `ngfor`, `ngif` ... all angular features + this won't work if this string is coming from backend – Robert Jul 30 '18 at 13:36
  • @Robert this will never work because your Angular code (such as interpolation) needs to be compiled, and strings aren't compiled to be Angular code. –  Jul 30 '18 at 13:39
  • @MalinduSandaruwan the problem isn't with rendering html, the problem is with making angular interpolation, directives, ..., etc work after compiling it – Robert Jul 30 '18 at 13:44
  • @trichetriche exactly template get complied ahead of running it, i want to interpret strings in run time – Robert Jul 30 '18 at 13:47
  • You can't, that's what I'm telling you. –  Jul 30 '18 at 13:51
  • @trichetriche can you please try to find a solution, because i did it with jquery so there must be a way to do it with angular – Robert Jul 30 '18 at 14:19
  • No, there's no way. And this isn't the same principle as JQuery. If you only want to append a variable then use `\`hello ${name}\``, which is a [typescript raw string](https://basarat.gitbooks.io/typescript/docs/template-strings.html), but don't expect Angular to compile code after you have already compiled it. –  Jul 30 '18 at 14:21
  • @trichetriche i have edited the question please read it again – Robert Jul 30 '18 at 14:38

3 Answers3

1

can't you do it like below. When data updates you can regenerate sample.

Say after your server response comes (in your case http) you call handleResponse() function.

handleResponse(response) {
    this.sample = `<span>hello <span>` + this.name + '</span></span>`;
    // ...
}

Your HTML file will remain the same

In a similar way you can use if, else ect rather than inIf...

In this way you can construct the html that should be displayed.

Malindu Sandaruwan
  • 1,477
  • 2
  • 13
  • 27
  • explain how i can do that with string coming from http request please – Robert Jul 30 '18 at 13:47
  • assign the value from the request to name like this: this.name = name; – Katana24 Jul 30 '18 at 13:48
  • @Katana24 please write full code because i didn't understand what you have just said – Robert Jul 30 '18 at 13:51
  • actually both name and the html will be coming from the api i need to make it interactive so the html and the name will be changed, and it can also be `ngfor` and more – Robert Jul 30 '18 at 14:02
0

It should be like this:

name = `world!`;
sample = '<span>hello '+this.name+'</span>';

and in the html:

<div [innerHTML]="sample"></div>
Katana24
  • 8,706
  • 19
  • 76
  • 118
  • didnt reload this page and didnt see Malindus answer - removing – Katana24 Jul 30 '18 at 13:48
  • please show me how to do it if sample is coming from backend – Robert Jul 30 '18 at 13:52
  • @Robert see Malindu's answer – Katana24 Jul 30 '18 at 13:56
  • @Robert you keep asking additional questions - they need to be seperate and asked only when you've taken what was demonstrated here on board – Katana24 Jul 30 '18 at 14:23
  • my question was very clear `what I want to do exactly is to render text coming from the backend as a part of the angular template.` you just didn't read the description and went straight to read the codes – Robert Jul 30 '18 at 14:52
0

Say after your server response comes (in your case http) you call handleResponse() function.

handleResponse(response) {
    this.name = response.name
    // ...
}

then in you HTML file

<span>hello <span>{{name}}</span></span>

This is the normal angular practice. Also it's very easy to implement.

Malindu Sandaruwan
  • 1,477
  • 2
  • 13
  • 27
  • you should put this as an edit in your original answer Malindu as it doesnt answer the original question – Katana24 Jul 30 '18 at 13:55
  • now i have html template coming from the backend say with `ngfor="let item of items"` and i will get from the api these items and i should make them work together – Robert Jul 30 '18 at 14:00