19

I'm trying to write an Angular component that renders markdown files as part of the webpage, using the ngx-markdown library. Looking at the library's official demo, it has a list of files that it requires, which are then rendered from:

From the demo's app.component.ts:

  blockquotes = require('raw-loader!./markdown/blockquotes.md');
  codeAndSynthaxHighlighting = require('raw-loader!./markdown/code-and-synthax-highlighting.md');
  emphasis = require('raw-loader!./markdown/emphasis.md');
  headers = require('raw-loader!./markdown/headers.md');
  horizontalRule = require('raw-loader!./markdown/horizontal-rule.md');
  images = require('raw-loader!./markdown/images.md');
  links = require('raw-loader!./markdown/links.md');
  lists = require('raw-loader!./markdown/lists.md');
  listsDot = require('raw-loader!./markdown/lists-dot.md');
  tables = require('raw-loader!./markdown/tables.md');

And from the demo's app.component.html:

<!-- HEADER -->
<section id="headers">
<h2 class="subtitle">Headers</h2>

<pre>{{ headers }}</pre>

<markdown>{{ headers }}</markdown>
</section>

There are other sections that read from the other requires, but the syntax is the same.

What I'm trying to do is to have a method that changes which file the <markdown> tag reads from. Here's what I have so far:

  // Markdown variable.
  markdown;

  ngOnInit() {
    this.setMarkdown('home.md');
  }

  setMarkdown(file: string) {
    const path = 'raw-loader!./assets/markdown/' + file;
    this.markdown = require(path);
  }

I'm obviously doing something wrong, since I get a compiler error:

ERROR in src/app/app.component.ts(24,21): error TS2591: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.

What am I doing wrong, and how would I go about writing a method that changes the markdown source and actually works?

3
  • 2
    require is used by the package loader, not meant to be used on your typescript. Not understanding what you are trying to achieve, that library already supports path to file npmjs.com/package/ngx-markdown#directive Commented Jun 3, 2019 at 22:48
  • I'll have to try that; I hadn't seen that part of the documentation before Commented Jun 3, 2019 at 22:51
  • And success! If you could rephrase your comment as an answer, @penleychan , I'd be happy to give you the reputation for answering the question. Commented Jun 3, 2019 at 22:56

3 Answers 3

13

Based on the documentation here, you can load file via [src]:

<!-- loaded from remote url -->
<div markdown [src]="'path/to/file.md'" (load)="onLoad($event)" (error)="onError($event)"></div>
Sign up to request clarification or add additional context in comments.

5 Comments

path is relative.
Also, if you put your .md files in assets, you can use 'assets/yourfile.md' has the path
@RoyerAdames no matter what I did as the src path, I would get a 404. Putting it in assets finally got it to render. thanks for this.
Note that if the path is hardcoded (like in this example), you don't need the square brackets or double quotes. So the example can be simplified to just: src='path/to/file.md'
Also note that in order to serve files from your assets folder, it needs to be listed in your angular.json config: build > options > assets ["src/assets"]
3

After lot of trials and errors, there is one more approach for dynamic rendering of markdown using ngx-markdown package via http calls.

Use HttpClient to make http call for md files:

import { HttpClient } from '@angular/common/http';
import { MarkdownService } from 'ngx-markdown';

export class AppComponent {
  title = 'personal-blog';
  markdownRaw ='';
  markdown='';
  
  constructor(private mdService:MarkdownService, private 
 httpClient:HttpClient){ }

  async ngOnInit() {
    this.markdownRaw = await this._httpClient.get(`/assets/hello.md`, 
    {
      responseType: 'text'
    }).toPromise();
        
    this.markdown=this.mdService.compile(this.markdownRaw);
  }
    
  onLoad(data:any) {
    console.log(data);
  }
         
  onError(data:any){
    console.log(data);
  }
}

Now use the declared and initialized variable as data property in markdown directive:

<markdown [data]="markdown" (load)="onLoad($event)" (error)="onError($event)"></markdown>

Comments

-1

In general, you can load md files as string with the HTTP client

async ngOnInit() {
    this.md = await this.http.get(`/assets/posts/1.md`, 
                    { responseType: 'text'}).toPromise();
}

Live editor example

https://stackblitz.com/edit/angular-reading-markdown-in-global-assets?embed=1&file=src/app/app.component.ts

Source

https://fireflysemantics.medium.com/loading-markdown-files-with-the-angular-httpclient-155e31acab68

1 Comment

Is there a way to do this, but (dynamically) for every .md file under a folder?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.