1

I am trying to display code in html and prettify it using Google Code prettify. I am almost close to completion of my requirement, but when I try to externalize the file and pull code from it, it isn't working.

Here is my ts code snippet.

demoJavaCode: any;
demoJavaCodeFromFile: any;

ngOnInit() {
    this.demoJavaCode = 
      `<pre><xmp class="prettyprint">
         public class A {
             public static void main(String args[]) {
             }
         }
        </xmp></pre>`;
 }

ngAfterViewInit() { 
  PR.prettyPrint();
}`

In template, I am fetching it like this.

<p  [innerHtml] ="demoJavaCode | trustedHtml"></p>

It works well, the paragraph which has code in it is highlighted/prettified only when it is sanitized using trustedHTML pipe.

But when I just tried to externalize the code to an external file having the exact same code content it's not working.

Here is my ts snippet.

this._http.get("assets/java_code.txt").map(res => res.text()).subscribe(
      response => {
        this.demoJavaCodeFromFile = response;
      },
      error => {
        this.componentErrorMessage = error;
      },
      () => {
        console.log('File successfully loaded..');
      }
    );

What could be wrong here? Any pointers and suggestions would help.

srk
  • 4,857
  • 12
  • 65
  • 109
  • 1
    Im assuming 'PR.prettyPrint()' calls a flobal API that does the code prettyfying? If you call that after you assign this.demoJavaCodeFromFile, in the success function of subscribe? – Ahmed Musallam Apr 09 '17 at 17:53
  • @AhmedMusallam, It does, and it expects the code to be attached to the document unless a root is explicitly passed in, and it does not enter shadowRoots or template nodes. See [declaration](https://github.com/google/code-prettify/blob/master/src/prettify.js#L1530) – Mike Samuel Apr 09 '17 at 20:48

1 Answers1

9

You should call PR.prettyPrint(); inside the ngAfterViewChecked component lifecycle hook

take a look at this plnkr: https://plnkr.co/edit/wDJCKx3RjpJID2Nb6j2L?p=preview

here is the code from the plnkr:

//src/app.ts 
import {Component, NgModule, VERSION, AfterViewChecked} from '@angular/core'
import { FormsModule }   from '@angular/forms';
import {BrowserModule} from '@angular/platform-browser'
import { HttpModule } from '@angular/http';
import { Http } from '@angular/http';

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <button (click)="refresh()">refresh</button>
      <div [innerHtml]="code"></div>
    </div>
  `,
})
export class App implements AfterViewChecked {
  name:string;
  code: string;
  constructor(private http: Http) {
    this.name = `Angular! v${VERSION.full}`;
  }
  refresh(){
    this.http.get("javacode.html")
    .subscribe(
      res => {
        this.code = res._body;
      },
      ()=>{},
      ()=>{})

  }
  ngAfterViewChecked(){
      console.log('ngAfterViewChecked')
      PR.prettyPrint();
  }
}

@NgModule({
  imports: [ BrowserModule, HttpModule, FormsModule],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}
//--------------------------------------
//src/javacode.html
<pre class="prettyprint">
  public class Cube {

    int length;
    int breadth;
    int height;
    public int getVolume() {
        return (length * breadth * height);
    }
}
</pre>
Ahmed Musallam
  • 9,523
  • 4
  • 27
  • 47
  • How do you import PR? I get " Cannot find name 'PR' " – Wenneguen Aug 18 '17 at 14:54
  • 4
    you cannot "import" it because it is not a module, you can declare PR as var like `declare var PR;` OR you can use it from window namespace like `var PR = window["PR"]` – Ahmed Musallam Aug 18 '17 at 15:55
  • @ahmed-musallam Thanks for your solution. Do you know why it doesn't work in `ngAfterViewInit` ? Putting code to `ngAfterViewChecked ` it's a not good Idea because it fired every time when something changes on the view, event if you use `OnPush` strategy – Artem Halas Dec 28 '18 at 18:35
  • @ArtemGalas this answer pertains to Angular 2, I am not sure if things changed after angular 2. The main point is, you want to call `PR.prettyPrint();` when the DOM has rendered and also make sure that your entire template is not being updated after you've called `PR.prettyPrint();` – Ahmed Musallam Dec 28 '18 at 21:26