swagger-api / swagger-api/swagger-ui

Swagger example payload lost on Single Page App

Open
#4,961 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

type: support
Dominant language
JavaScript
Stars
29k
Forks
9.3k
Avg merge
2d 23h
Merged PRs (30d)
25

Description

Q&A (please complete the following information)
  • OS: [macOS
  • Browser: chrome
  • Version: 69.0.3497.100 (Official Build) (64-bit)
  • Method of installation: yarn
  • Swagger-UI version: 3.19.0
  • Swagger/OpenAPI version: 3.19.0
  • React Version: 16.5.0
Content & configuration

Here is my initialization of the SwaggerUI inside a react component:

        // ...spec is of type `Object={}`
        this.parser.dereference(parsedSource).then(spec => {
            this.ui = SwaggerUi({
                dom_id: '#swaggerContainer',
                spec: spec,
                presets: [presets.apis],
                deepLinking: true
            })
            this.authorize()
        })
Describe the bug you're encountering

When our docs component initially loads for the first time the <RequestBodyEditor> component is rendered; However, if I route to a different page via react-router-dom then return to my docs component; the <RequestBodyEditor> component is not being rendered.

Below are two screen shots:

  • first image is the initial render of docs component with <RequestBodyEditor> component
- second image is with missing `` component.

Also note that every time that we toggle between one page and back to the docs page, a new React root is mounted. Below are two images describing what I mean:

  • first image is the initial load, one can see the swagger React node loaded using ReactDOM
    image

  • second image shows multiple swagger React nodes:
    image

The first <_class2></_class2> react node contains the <RequestBodyEditor>, and all consecutive ones are missing <RequestBodyEditor>.

Attempts to fix:

I used ReactDOM.unmountComponentAtNode(node) on componentWillUnmount and node is the node returned by the ref attribute attached to the <div id="swaggerContainer" ref={this.handleRef} />. This did not solve the issue; however it did remove each <_class2></_class2> from memory, so they were not stacking on each other like on image two.

Next Attempt - did solve my issue:

When the first component loaded with a successful swagger instance with <RequestBodyEditor> component I would cache the return value from this.ui = SwaggerUi({...}). Whenever the docs component would re-mount and cachedSwaggerUI != null, I would use its render function with the node return by the ref attribute. I would not call SwaggerUI again in this scenario.

if (cachedSwaggerUI != null) {
    cachedSwaggerUI.render(node)
}
Expected behavior

I expect <RequestBodyEditor>, anytime my docs component is mounted.

Additional context or thoughts

This could be an issue because we are on React v16 and swagger is on v15.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the route-remount behavior around SwaggerUI, RequestBodyEditor, and the ReactDOM mounting lifecycle. Compare a fresh SwaggerUI initialization with reusing its render function, and verify that RequestBodyEditor appears on every docs mount without accumulating React roots. No specific source file or test is named in the issue.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.