Skip to content

Add html dynamically to an element #23916

Closed

Description

@camilo-5972

I need to dynamically add an html to an element of the template

This is the code that I have in my component


import { Component, OnInit, ViewChild, TemplateRef } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  private title:string = 'app';
  private viewContent:any;
  private viewFile:string;

  constructor(private http: HttpClient){}

  ngOnInit(){
  	this.http.get('assets/views/default.html', {responseType: 'text'}).subscribe(data => {
    	this.viewFile = 'default.html';
    	this.viewContent = data;
	  });
  }
}

The app.component.html

<div style="text-align:center">
  <h1>
    Welcome to {{ title }}!
  </h1>
  <img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
</div>
<h2>The next view is load from {{ viewFile }} </h2>

<div>{{ viewContent }}</div> ==> this shows: <div> Default template {{viewFile}} </div>
<div [innerHTML]="viewContent"></div> ==> this shows: Default template {{viewFile}}

And the file that I want to load that is located in the route: assets/views/default.html

<div>
	Default template {{viewFile}}
</div>

Current behavior

  • There is a folder with an html file
  • The file is read as text using a get http request
  • The content is shown in the template

The problem I have is that the content of the html is loaded as text in the template. I could solve that part if I used [innerHtml] and passed the contents of the html file, but I have a problem when the file has interpolation variables {{var}} because these are not loaded by Angular

Expected behavior

Dynamically load html files located in a project folder and display them in some element of the template detecting its variables when adding it. The following is what is expected to be displayed in the template when the viewContent variable is loaded into some element:

Default template default.html

Environment


Angular version: 4.1.3

Browser:
- [x ] Safari (desktop) version 11.1

For Tooling issues:
- Node version: 8.11.1
- Platform:  Mac High Sierra 10.13.4

Activity

  1. mlc-mlapis commented on May 15, 2018

    @mlc-mlapis
    Contributor

    @camilo-5972 ... you can pass just pure HTML code using [innerHTML]="yourProperty". No Angular bindings are available because you don't have Angular compiler in run-time with AOT mode, so there is nothing what could compile those bindings to JS as Angular compiler is doing.

  2. camilo-5972 commented on May 15, 2018

    @camilo-5972
    Author

    So, is there no way to dynamically load html into my template by interpreting the variables it might have?

  3. mlc-mlapis commented on May 15, 2018

    @mlc-mlapis
    Contributor

    @camilo-5972 ... not by the way as you think. You have to always see that AOT Angular app is compiled ahead of time. Not in run-time. There are ways which allow you to get some level of dynamic functionality today as:

    • the same way as the https://angular.io app is using (parsing HTML and dynamic instantiation of components),
    • mix AOT app with JitCompiler (it allows you to really compile templates in run-time but not recommended because of security and performance factors),
    • re-think the concept what you are trying to get (and not fight with Angular concept).
  4. IgorMinar commented on May 22, 2018

    @IgorMinar
    Contributor

    @mlc-mlapis angular.io now uses Angular Elements

    @camilo-5972 you can take a look at https://angular.io/guide/elements which is suitable for certain use-cases similar to yours, but in general you shouldn't expect to be able to load a string at runtime and have it be interpreted and processed as an Angular template at runtime. This is primarily because at runtime the template compiler is no longer available due to its size and runtime overhead.

    What you can do is to precompile templates at build time and lazily load them. As I mentioned Angular Elements is likely the easiest way to do this.

  5. hinalshah91 commented on Jul 19, 2018

    @hinalshah91

    Even in my case, I am getting the html content from an api response. I need to inject it using [innerHTML]="pageContent". But the (click) event doesn't work in that case. Also, there is a slider which I want to initialize but angular doesn't recognize that tag. (slider I am trying to implement is ngx-swiper)

  6. mlc-mlapis commented on Jul 19, 2018

    @mlc-mlapis
    Contributor

    @hinalshah91 ... [innerHTML]="anyExpression" supports only pure HTML code to be passed because you don't have Angular compiler in run-time at all. Comments above explain it so why are you repeating the same again?

  7. hinalshah91 commented on Jul 19, 2018

    @hinalshah91

    @mlc-mlapis is there any other way I can inject my pageContent to html?

  8. mlc-mlapis commented on Jul 19, 2018

    @mlc-mlapis
    Contributor

    @hinalshah91 ... the first question is why do you need it in fact. Because probably you should re-think the concept and you will see that the things could be done more elegantly and conceptually as Angular supposes.

    Btw ... if you are talking about any HTML code which contain Angular bindings (like inputs / outputs, ...) ... actually there is only one way ... loading JitCompiler into AOT app and compile that HTML code directly in run-time. This way is not recommended because of performance and security point of view.

    A new renderer call Ivy is on the way for Angular 7 which opens many new ways and one of them is your case ... you can see the Ivy status here https://is-angular-ivy-ready.firebaseapp.com/#/status.

  9. suparnavg commented on Dec 5, 2018

    @suparnavg

    @camilo-5972 the way I can get this working is to use ${this.variable} in your html string and then populate the this.variable in the component to get it to display the variable value. Where I'm stuck is getting the view to update if this.variable changes..

  10. angular-automatic-lock-bot commented on Sep 14, 2019

    @angular-automatic-lock-bot

    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.

  11. locked and limited conversation to collaborators on Sep 14, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions