Display raw html - Angular 6 - html

I am looking to display the raw HTML code (example.component.html) below 'example works!'. The page should display the following:
example works!
<p>
example works!
</p>
I can find various resources showing how this can be done using AngularJS but not Angular 6.
I have tried to use [innerHTML] but this didn't work.
<p>
example works!
</p>
example.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'rt-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
app.component.html
<div style="text-align:center">
<rt-example></rt-example>
</div>
OUTPUT . . link to image

You can use the ViewContainerRef to get the nativeElement, and get its innerHTML.
Just a warning : this won't be your HTML code, but the compiled code.
Here is an example : stackblitz
export class AppComponent {
htmlContent: string;
constructor(private view: ViewContainerRef) {
setTimeout(() => this.htmlContent = (view.element.nativeElement as HTMLElement).innerHTML);
}
}
EDIT If you want the uncompiled code, you should use this notation : stackblitz
import { Component, ViewContainerRef } from '#angular/core';
import * as template from "./app.component.html";
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
htmlContent: string = template.default;
constructor(private view: ViewContainerRef) {
}
}
But I suggest you use the latest versions of typescript & Angular, since I'm not sure when it has been introduced.

Get a reference pointing to that component using ViewChild, like
export class AppComponent {
#ViewChild(ExampleComponent, { read: ElementRef }) exampleComponent;
}
Then you can access its HTML with nativeElement.innerHTML.
So you could change your app.component.html to this:
<div style="text-align:center">
<rt-example></rt-example>
</div>
{{exampleComponent.nativeElement.innerHTML}}

In HTML, you need to use entities to show the reserved characters.
<p>example works!</p>
<code><p>example works!</p></code>
For example:
& is equivalent to &
< is equivalent to <
> is equivalent to >
However solution using angular would be:
Component:
export class SomeComponent {
code :string = `<p>example</p>`
}
HTML:
<code>{{this.code}}</code>
OR Use InnerText instead of InnerHTML
<p [innerText]="code"></p>
https://stackblitz.com/edit/angular-5cpmcr

Related

Angular: sanitizer.bypassSecurityTrustHtml does not render attribute (click)

I try to render a button and it works fine, but when I click the button it doesn't execute alertWindow function, help!:
app.component.ts:
import {
Component,
ElementRef,
OnInit,
ViewEncapsulation } from '#angular/core';
import { DomSanitizer, SafeHtml } from "#angular/platform-browser";
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
encapsulation: ViewEncapsulation.ShadowDom,
})
export class AppComponent implements OnInit {
public content: SafeHtml;
constructor(private sanitizer: DomSanitizer) {}
async ngOnInit() { this.renderButton(); }
alertWindow() { alert("don't work"); }
renderButton() {
this.content =
this.sanitizer.bypassSecurityTrustHtml(`
<button (click)='connectWallet()' class="button">
Connect your wallet
</button>`);
}
app.component.ts;
<div [innerHTML]="content"></div>
Solution
Based on what I understand you wanted to display HTML dynamically at runtime? then solution is to use
ComponentFactoryResolver
and ViewContainerRef
It will be better if you can provide more details, what you are trying to achieve, so that people can guide you
Why it didn't work?
It doesn't work because it is outside of angular, when you use innerHTML then whatever you passed to it is pure vanilla HTML and JavaScript
Try this example
(window as any).alertWindow = function () {
alert("don't works");
};
#Component({...})
export class AppComponent {
...
renderButton() {
this.content = this.sanitizer.bypassSecurityTrustHtml(`
<button onclick='alertWindow()' class="button">Connect your wallet</button>
`);
}
}
It works right?
As you can see I have moved alrertWindow function outside of component's class and added to window variable and also changed (click) to onclick

Return plain JSON when calling specific router URL

I have an Angular application that shows different pages. I can navigate by (hamburger) menu or by calling the specific route (e.g. http://localhost/samplepage). Now I want to return plain JSON content when entering a specific route (e.g. http://localhost/myjson).
How can I manipulate the response so that it throws away all the Angular generated component code and instead return my plain JSON?
This seems to work:
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
name = 'Angular';
ngOnInit() {
const obj = {
name: 'Torsten',
age: 54
}
const thefile = new Blob([JSON.stringify(obj)], { type: "application/json" }) ;
let url = window.URL.createObjectURL(thefile);
window.location.href = url;
}
}
1. Solution
You can use json.stringify to show only plain json. Therefore you will still need a component, unless you want to have some guard methods to handle it there.
Like:
TS:
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
getStringFromJson(): string {
JSON.stringify(this.someService.method())
}
}
HTML:
{{ getStringFromJson() }}
Stackblitz: https://stackblitz.com/edit/angular-yvamcm
2. Solution
Put a JSON file into your assets folder, which you edited before. Then use the Router service to redirect to this file in any time, but going to this file will cause, that you are not in the angular application anymore

Component Interaction #Input

I would like a component to send input to another component. Below is the code .ts and .html. of the two components.
Now the problem is that the html page of the parent component also shows the html part of the child component ... I want the component to pass only one string to the child component
Parent.ts
import ...
#Component({
selector: 'app-parent',
templateUrl: './parent.html',
styleUrls: ['./parent.css']
})
export class ParentComponent implements OnInit {
sostegno : string;
constructor() { }
ngOnInit() { }
avvia1() {
this.sostegno = "xxx";
this.router.navigate(['./xxx'], { relativeTo: this.route });
}
avvia2()
this.sostegno = "yyy";
this.router.navigate(['./yyy'], { relativeTo: this.route });
}
}
Parent.html
<div>
...
</div>
<app-child [sostegno]="sostegno"></app-child>
Child.ts
import ...
#Component({
selector: 'app-child',
templateUrl: './child.html',
styleUrls: ['./child.css']
})
export class ChildComponent implements OnInit {
#Input() sostegno : string;
constructor() { }
ngOnInit() {
console.log(this.sostegno);
}
}
There are some changes which you need to make because looking at the code which your currently have it seems incomplete.
You are using this.router without injecting the Router class in your constructor.
You are using this.route without injecting the ActivatedRoute class in your constructor.
To test that your parent > child interaction is working you can remove your param and instead place a test for the html
<app-child [sostegno]="'Test'"></app-child>
This should work for your ngOnInit function which is inside of your child component. If this works all you need to do now is either initialize sostegno in your parent component else your console log inside your child component will not reflect the changes when you call avvia1 or avvia2 inside of your parent class.
Hope this helps!

Angular html nesting

Let's say I have in some upper level class some angular template code that looks like this
<outer-component>
<a></a>
</outer-component>
Where <a> can be any module that extends a certain interface defined elsewhere, is there a way for <outer-component> be able to take <a> or whatever is placed inside the tags and communicate with it specifically be able to listen to functions or bind to variables in a way that is as succinct as the snippet above?
If you want to share data between a parent and a child (hierarchical relationship) you can use EventEmitter to allow the parent to get data from the child.
In the child component:
import { Component, Input, Output, EventEmitter } from 'angular/core';
#Component({
selector: 'app-child',
template: `
<h3>Child</h3>
Say {{message}}
<button (click)="sendMessage()"></button>
ยด,
styleUrls: ['pathToStyles.css']
})
export class ChildComponent {
message: string = "Hello world";
#Output() messageEvent = new EventEmitter<string>();
constructor() {}
sendMessage() {
this.messageEvent.emit(this.message);
}
}
In the parent component:
import { Component } from '#angular/core';
#Component({
selector: 'app-parent',
template: `
Message: {{message}}
<app-child (messageEvent)="receiveMessage($event)"></app-child>
`,
styleUrls: ['pathToStyles.css']
})
export class ParentComponent {
constructor() { }
message:string;
receiveMessage($event) {
this.message = $event
}
}

Angular 2 component inherit with onClick

I would like to inerit from component and add onClick method, how can I do it?
I want to have only one html file.
Here is a basic example -
I have a temple file with this html code-
<h1>h1</h1>
<h2>h2</h2>
I want to inherit this component and add OnClick method on h1.
Thanks in advance.
You can just add that component with function and a variable that sets to true on click.
<button (click)="toggleComponent()"></button>
<app-example-component *ngIf="variable">
ts:
variable = false;
toggleComponent() {
this.variable = !this.variable;
}
You can extend component like I did as below:
Plunker Link
https://plnkr.co/edit/azixm9?p=preview
//our root app component
import {Component, NgModule, VERSION} from '#angular/core'
import {BrowserModule} from '#angular/platform-browser'
#Component({
selector: 'my-app',
template: `
<div>
<h2 (click)="callMe()">Hello {{name}}</h2>
<comp-one></comp-one>
</div>
`,
})
export class App {
name:string;
constructor() {
this.name = `Angular! v${VERSION.full}`
}
public callMe(compName: any): void {
alert("App Component will handle this functionality")
}
}
#Component({
selector: 'comp-one',
template: `<h2 (click)="callMe()">Click Me</h2>`,
})
export class ComponentOne extends App {
}
#NgModule({
imports: [ BrowserModule ],
declarations: [ App, ComponentOne ],
bootstrap: [ App ]
})
export class AppModule {}