2

I am new to angular. I am trying render some dynamic template strings that are coming from a server in a component.

The component looks like this -

<div [innerHTML]='templateString'></div>

In component.ts file, we have

obj = {
   prop: 'text to display'
}
templateString = '<p class="text-primary">{{obj.prop}}</p>' // this is dynamic, e.g. received from an http request

If we leave it like this, it will render as '{{obj.prop}}' whereas I want it to show is 'text to display'. Currently I have written a script that takes the templateString and obj and returns the properties by using .split('{{') etc. Is there some simpler built-in way to do this in angular? I.e. compiling the template strings dynamically onChanges or onInit, so that I can take advantage of ngFor to display values inside an array property for instance.

arr = [
   {prop: 'text1'},
   {prop: 'text2'}
]
templateString = '<p *ngFor="let item of arr">{{item.prop}}</p>'

Currently I am using a custom syntax [[arr::

{{this.prop}}

]] which my script can read and iterate over arrays, but it is pretty unreliable and non standard.

I have seen this Angular: bind variables inside [innerHtml], but it seems overqualified since I do not need to put other components inside the template string. Just standard html, with some directives like ngFor, ngIf etc,

Pedro Coelho
  • 1,411
  • 3
  • 18
  • 31
  • 1
    Interpolation {{}} is used on HTML, on TS you can assign value to templateString by obj.prop – Mridul Feb 25 '20 at 06:32
  • Yeah .. you just need to do `templateString = obj.prop`. – jophab Feb 25 '20 at 06:33
  • Change ```'{{obj.prop}}'``` to ```this.obj.prop``` like, ```templateString = this.obj.prop``` , Example: https://stackblitz.com/edit/my-angular-starter-cnp4yj – Maniraj Murugan Feb 25 '20 at 06:37
  • Does this answer your question? [Angular 2 innerHTML ignoring form tags](https://stackoverflow.com/questions/38986310/angular-2-innerhtml-ignoring-form-tags) – vicpermir Feb 25 '20 at 06:41
  • templateString is expected to contain html. I have updated my question. Using this.obj.prop will not work in this case. – Mitth'raw'nuruodo Feb 25 '20 at 06:43
  • As it stands, you would need the Angular JIT compiler to be shipped to the frontend and then dynamically compile a component out of your string. This is significant work if you don't know how, and comparatively slow. I'd try to change the problem instead if possible. – Ingo Bürk Feb 25 '20 at 06:46
  • That is sort of what I am doing now. But you are right it is unreliable at best, due to my limited skills. Because I can not make use of *ngFor, I am using a custom syntax '[[arr::

    {{this.prop}}

    ]]' to identify and iterate over arrays, and I had to specify this to the people who are preparing the strings that are sent from the server. Not to mention it will break if the string contains '[[' or '::' or '{{' etc normally without referencing a variable. I was hoping the angular team has made some provision for cases like this.
    – Mitth'raw'nuruodo Feb 25 '20 at 07:02
  • Well, as I said, you can ship the compiler and dynamically compile the template. It's just a lot of work, but it gives you something to search for. It's certainly easier than implementing your own entire language and framework. – Ingo Bürk Feb 25 '20 at 07:09
  • Perhaps I should use something like handleBars to compile these strings during onInit or onChanges,and make sure the strings follow handlebars syntax. What do you think? – Mitth'raw'nuruodo Feb 25 '20 at 07:18

2 Answers2

0

I think you can just use inline concatenation

`this is the string ${this.foo} more string here`
0

No rocket science needed. This will work for you!

templateString = '<p class="text-primary">'+  this.obj.prop + '</p>' ;
R0b1n
  • 513
  • 1
  • 5
  • 28