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);
        }
      }
    }