0

I want to display the links that are stored in a json file like this:

[
    {
        "heading": "Waswas",
        "content": "./waswas.html"
    },

    {
        "heading": "Flu",
        "content":""
    }
]

In my component.ts file I parse that to an array variable like this:

 public treatmentsList:{heading: string, content: string}[] = treatments;

Then in my component.html file I have this:

<div>
    <h1>
        {{treatmentsList[0].heading}}
    </h1>
    <span [innerHTML]="getContent(treatmentsList[0].content) | async"></span>
</div>


But it shows the link instead of the file

The component.ts file:

import { Content } from '@angular/compiler/src/render3/r3_ast';
import { Component, NgModule, OnInit } from '@angular/core';
import { SafeHtml } from '@angular/platform-browser';
import { Observable } from 'rxjs';
import { ContentService } from '../content.service';
import treatments from "./treatments.json"

var heading = "hTempl"
@Component({
  selector: 'app-treatment',
  templateUrl: './treatment.component.html',
  styleUrls: ['./treatment.component.css']
})

export class TreatmentComponent implements OnInit {
 public treatmentsList:{heading: string, content: string}[] = treatments;
  
 constructor(
  private readonly contentService: ContentService
)  {}

public getContent(path: string): Observable<SafeHtml> {
  return this.contentService.get(path);
}

  ngOnInit(): void {

  }
}

app.module.ts:

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { TreatmentComponent } from './treatment/treatment.component';
import { PrgrefComponent } from './prgref/prgref.component';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent,
    TreatmentComponent,
    PrgrefComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

  • 1
    You'll need to in-line the html in the JSON file, or do an http request to get the html document within your component.ts. – John Aug 29 '21 at 06:24
  • @JohnD I don't want to put it in the son for IDE Features. – M. Yusuf Suleman Aug 29 '21 at 06:28
  • 1
    Then you'll need to build a service to fetch the html files and then sanitize them with the dom sanitizer. If you post your full component.ts and component.html I can help further. – John Aug 29 '21 at 06:30
  • @JohnD How do I do that? – M. Yusuf Suleman Aug 29 '21 at 06:33
  • 1
    I posted an answer, reply if you have questions. – John Aug 29 '21 at 06:52
  • @JohnD I added that file with the same name as you said in the answer in the same directory as the same component said in the question, and is still not working. – M. Yusuf Suleman Aug 29 '21 at 08:56
  • 1
    Check the network tab in your browser, are you getting an error there? Any console errors? – John Aug 29 '21 at 10:43
  • @JohnD I thought I only needed to add this new thing called a service and it should work then because I thought that the only thing you posted was that. Then looking again at it I realized that you gave me more code that I wrote but it gave me a constructor error that I solved by adding `{}` after the `)` on the constructor; but when I refresh the page it is blank. . – M. Yusuf Suleman Aug 30 '21 at 07:26
  • 1
    Post your component.ts and any console errors – John Aug 30 '21 at 07:28
  • @JohnD No errors. The component.ts file is in the question. – M. Yusuf Suleman Aug 30 '21 at 11:38
  • 1
    That can't be the entire component.ts file, I can't help you further without additional portions of your component.ts or a console/network error message. – John Aug 30 '21 at 12:09
  • 1
    @JohnD, Sorry for late reply; I wrote the code in the post but it was not there, I could have not clicked the save button or some evil person removed it. I have put the whole file at the end of the question now. – M. Yusuf Suleman Aug 31 '21 at 15:52
  • Your component.ts looks good, can you update the component.html as well? Have you tried changing `"content": "./waswas.html"` to `"content": "/waswas.html"`? – John Sep 01 '21 at 07:43
  • You may also need to import `HttpClientModule` as described here: https://angular.io/guide/http – John Sep 01 '21 at 07:52
  • @John It now says [object Object]. – M. Yusuf Suleman Sep 02 '21 at 07:50
  • Getting closer at least. Update your question with the modified code please. – John Sep 02 '21 at 07:56
  • @John I only changed the `app.module.ts` file and included it at the end of the question. – M. Yusuf Suleman Sep 03 '21 at 11:07
  • Can you confirm if you're `component.html` has been updated to use the `| async` as well? – John Sep 07 '21 at 06:33
  • @John Sorry for very late reply'; I have added the `| async` to the code in the html, now it is displaying nothing, only the rest of the site. – M. Yusuf Suleman Sep 11 '21 at 03:58
  • Can you add the updated component.html to your question? – John Sep 11 '21 at 06:26
  • @John I have changed it now. – M. Yusuf Suleman Sep 12 '21 at 07:01
  • That all looks correct, try wrapping your `` in ``. – John Sep 12 '21 at 07:18

1 Answers1

2

Create a service to fetch your html documents and then sanitize them.

content.service.ts

import { HttpClient, HttpHeaders  } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root',
})
export class ContentService {
  constructor(
    private readonly http: HttpClient,
    private readonly sanitizer: DomSanitizer
  ) {}

  public get(path: string): Observable<SafeHtml> {
    const headers = new HttpHeaders({
      'Content-Type':  'text/plain',
    });
    return this.http.get(path, {
      headers,
      responseType: 'text'
    }).pipe(
      // This is unsafe if the path and content is not under your control
      map(html => this.sanitizer.bypassSecurityTrustHtml(html))
    );
  }
}

Then in your component.ts use the service

constructor(
  private readonly contentService: ContentService
)

public getContent(path: string): Observable<SafeHtml> {
  return this.contentService.get(path);
}

Finally your html

<span [InnerHTML]="getContent(treatmentsList[0].content) | async"></span>
John
  • 1,240
  • 9
  • 13