Search code examples
angularredocredocly

Redoc content is not rendering in angular application


I'm trying to integrate Redoc into my Angular project, and it seems that Redoc content is not rendering.

Here is what I have done so far:

angular.json

    "scripts": [
      "src/assets/js/redoc.standalone.js"
    ]

The component I am testing on

dashboard.component.ts

import { Component, OnInit } from '@angular/core';


declare var Redoc: any;

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit {

  constructor() { }

  ngOnInit() {
    this.initDocs();
  }


  initDocs(){
    Redoc.init('http://petstore.swagger.io/v2/swagger.json', {
    scrollYOffset: 60,
    hideDownloadButton: true
    }, document.getElementById('redoc'))}

}

dashboard.component.html

<mat-toolbar color="primary">
  <span>Dashboard</span>
</mat-toolbar>


<p>
  dashboard works!
</p>
test

Screenshot Dashboard page

enter image description here

Console - Logs

enter image description here

console rendered html structure enter image description here


Solution

  • [solved last week] After conducting my research and not finding any solutions, I pondered why not utilize ElementRef from '@angular/core'; to query the selector by id. To my surprise, this approach worked. To save others the trouble of searching for a solution, here is what I did to integrate Redoc into my Angular application:

    Install redoc via npm

    npm i redoc
    

    Link

    Add redoc scripts to angular.json

        "scripts": [
          "node_modules/redoc/bundles/redoc.standalone.js"
        ]
    

    Your component (in my case dashboard.component.ts)

    import { Component, ElementRef, OnInit } from '@angular/core';
    
    declare var Redoc: any;
    
    @Component({
      selector: 'app-dashboard',
      templateUrl: './dashboard.component.html',
      styleUrls: ['./dashboard.component.scss']
    })
    export class DashboardComponent implements OnInit  {
      
      constructor(private el: ElementRef) { }
    
      ngOnInit() {
        this.initDocs();
      }
    
    
      initDocs(){
        const container = this.el.nativeElement.querySelector('#redoc');
    Redoc.init('http://petstore.swagger.io/v2/swagger.json', {
        scrollYOffset: 60,
        hideDownloadButton: true
      }, container);
      
      }
    
    }
    

    This example uses Angular's ElementRef to access the native DOM element and the ngOnInit lifecycle hook to ensure that the component is ready before initializing Redoc.

    Optional: You can create a service:

    // redoc.service.ts
    import { Injectable } from '@angular/core';
    
    declare const Redoc: any;
    
    @Injectable({
      providedIn: 'root'
    })
    export class RedocService {
      initDocs(specUrl: string, options: any, container: HTMLElement): void {
        Redoc.init(specUrl, options, container);
      }
    }
    

    Use the Redoc Service in a Component:

    // app.component.ts
    import { Component, OnInit, ElementRef } from '@angular/core';
    import { RedocService } from './redoc.service';
    
    @Component({
      selector: 'app-dashboard',
      template: '<div id="redoc"></div>',
      styleUrls: ['./dashboard.component.css']
    })
    export class DashboardComponent implements OnInit {
    
      constructor(private redocService: RedocService, private el: ElementRef) {}
    
      ngOnInit(): void {
        this.initDocs();
      }
    
      private initDocs(): void {
        const redocContainer = document.getElementById('redoc');
    
        if (redocContainer) {
          this.redocService.initDocs('http://petstore.swagger.io/v2/swagger.json', {
            scrollYOffset: 60,
            hideDownloadButton: true
          }, redocContainer);
        }
      }
    }