Swagger-ui: Impossible to submit required params in react app which is using SwaggerUi component

Created on 19 Jul 2018  路  16Comments  路  Source: swagger-api/swagger-ui

Prerequisites

  • OS: macOS
  • Browser: chrome
  • Version: 67
  • Method of installation: npm
  • Swagger-UI version: 3.17.3
  • Swagger/OpenAPI version: OpenAPI 3.0

Content & configuration

Swagger UI is used inside react component. React version is ^16.3.2

Example Swagger/OpenAPI definition: https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml

Swagger-UI configuration options:

SwaggerUI({
  dom_id: "#swagger",
  url: spec_url,
})

Describe the bug you're encountering

Impossible to specify the required parameter for routes like /get/{petId}. The UI just remove it when I'm clicking on Try it Out -> Execute button.

To reproduce...

Steps to reproduce the behavior:

  1. Click on any route with required parameter. E.g. /pet/{petId}
  2. Click "Try it out" button
  3. Specify pet id
  4. Click on "execute" button
  5. See error - pet id was removed, petId field is red. UI doesn't send any http request

Expected behavior

UI sends the HTTP request and display the results

Screenshots

video

Additional context or thoughts

This is most visible issue that have direct impact on functionality. However, there are tons of JS errors in the chrome console. They appear on almost every stage: page load, authorization modal window, submiting requests, etc.

I think most of problems come from different react versions used in app and swagger ui

Other related issues: textarea with console curl command always show curl -X "undefined" instead of actual command(HTTP request is different)

usage in react@16 lock-bot integration bug

Most helpful comment

Fixed!

We've just released swagger-ui-react, which declares React as a peer dependency. I've tested this module within a React 16 create-react-app, and the required parameter issue is no longer present.

All 16 comments

I am facing the same issue. Also using swagger-ui imported into my own react project.

Hey @kokoc, this is because you're using React 16 in your project - we currently don't support that. You might be able to get away with isolating Swagger UI: consider using an iframe or Shadow DOM for the time being.

Take a look at the other tickets in epic: usage in react@16 for more context, and possible solutions we've come up with.

This _is_ something that we want to fix, but more input would be great 馃槃

Thanks for clarifications. You right, iframes fix the issue.

Here is a snippet that might be useful for other people:

    componentDidMount() {
        var url = 'your url';
        var page = `<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8">
    <title>Swagger</title>
    <link rel="stylesheet" type="text/css" href="https://unpkg.com/[email protected]/swagger-ui.css">


</head>
<body>

<div id="swagger-ui"></div>

<script src="https://unpkg.com/[email protected]/swagger-ui-standalone-preset.js"></script>
<script src="https://unpkg.com/[email protected]/swagger-ui-bundle.js"></script>

<script>
    window.onload = function() {
        // Build a system
        const ui = SwaggerUIBundle({
            url: "${url}",
            dom_id: '#swagger-ui',
            deepLinking: true,
            presets: [
                SwaggerUIBundle.presets.apis,
                SwaggerUIStandalonePreset
            ],
            plugins: [
                SwaggerUIBundle.plugins.DownloadUrl
            ],
            layout: "BaseLayout"
        })
        window.ui = ui
    }
</script>
</body>
</html>`;
        var frame = this.refs.frame;

        var ifrmDoc = frame.contentWindow.document;
        ifrmDoc.open();
        ifrmDoc.write(page);
        ifrmDoc.close();
    }
    shouldComponentUpdate() {
        return false;
    }
    render() {
        return (
            <div className="container">
                <iframe id="frame" ref="frame"/>
            </div>
        );
    }

Same issue for me - unable to submit required params from a SwaggerUI component in a react 16.5.2 app. Details all identical to above. If there's any more info I could provide that would be useful, let me know - Would love to know if there was any timeline for full react 16 support.

@tomwatt, I don't have a timeline for you, but just so you know - this _is_ on our radar. We see you!

Adding this note in case someone comes upon this issue and thinks "I'm not integrating this into a React 16 app, why might I be seeing this?"

This also happens in a dev environment running Swagger UI "standalone" with another React-dependent tool being used in the same dev install.

To recreate, install Storybook as a devDependency, and implement a simple one page Swagger UI display separately in the same dev environment (meaning, installed as a devDependency as well) following the Swagger UI documentation. Storybook's React dependency is hard-set, so it's impossible to avoid installing 16 in this scenario, and this bug is then exposed for any required field.

I'm looking at breaking either Storybook or Swagger into a separate project, but due to requirements around our project, both have to live in the same repository and aren't easily built separately.

If I can contribute to one of the outstanding issues in the React 16 epic, I'll give it a shot.

I'm glad I found this issue was raised, I always thought it was something in my code that was causing it grief and I just never had the time to look at it. Given that React 16 is pretty much the default now hopefully this can be addressed. I'm not sure what I can do to help it along but I certainly will be help to test the fix.

Hello, I solve this problem with these version

"react": "16.2.0",
"swagger-ui": "^3.9.1",

Hi everyone!

I'm going to be working on this in the near future. Since it largely involves integrations within existing applications, I'd like to have some folks test out what I come up with before we ship it.

If you'd like to help out, please email me (address in profile) and I'll be in touch.

thanks @kokoc for your temporary solution.
@shockey I emailed you -- i'm happy to help (also, sorry i somehow didn't find this issue before making a new one. feel free to close that one)

This works locally with webpack-dev-server while it doesn't work with a webpack build. Any ideas why?

So, I ran into this issue & solved it by removing the debounce on the input. That PR is available here: https://github.com/swagger-api/swagger-ui/pull/4982

Could other people affected merge in that PR to their project and see if it fixes their use case? If so, that PR should either be merged or we should investigate why that input was debounced when others aren't, if it needs to be, and if lodash or a homegrown debounce can be put in its place instead.

Fixed!

We've just released swagger-ui-react, which declares React as a peer dependency. I've tested this module within a React 16 create-react-app, and the required parameter issue is no longer present.

So, I have that case mentioned earlier.. I have an angular app! Why is there a react dependency conflict? Thanks to that comment and npm ls, I realize it's the dev dependency on storybook. Here's a quick working example of an angular 7 component using swagger-ui-react 3.22.0. Not shown is including the swagger css path (starting at node_modules) in angular.json, at json node: projects.your_project.architect.build.styles. Hope it's useful to someone!

import {
  AfterViewInit,
  Component,
  ElementRef,
} from '@angular/core'

import SwaggerUI from 'swagger-ui-react'
import { environment } from '@env/environment'
import { KeycloakService } from '@app/core/services'
import * as React from 'react'
import * as ReactDOM from 'react-dom'

@Component({
  selector: 'app-swagger',
  template: '<div class="swagger-container"></div>',
})
export class ApiDocsComponent implements AfterViewInit {

  constructor(private el: ElementRef, private keycloak: KeycloakService) {
  }

  ngAfterViewInit() {
    const props = {
      url: environment.api_base_url + '/v1/swagger.json',
      requestInterceptor: async a => {
        const token = await this.keycloak.getToken()
        a.headers['authorization'] = 'bearer ' + token
        return a
      },
    }
    ReactDOM.render(
      React.createElement(SwaggerUI, props, null),
      this.el.nativeElement,
    )
  }
}

@djeikyb brilliant find! thanks for writing this up 馃槃

I'm using this in a Vue app and it still shows curl -X "undefined" using swagger-ui: 3.22.0 and this code

<template>
    <div>
        <div id='swagger'></div>
    </div>
</template>

<script>
    import SwaggerUI from 'swagger-ui'
    import 'swagger-ui/dist/swagger-ui.css';
    import StandalonePreset from 'swagger-ui/dist/swagger-ui-standalone-preset';

    import {getProfile} from '../../store/identity'

    let swagger;
    export default {
        mounted() {
            this.$nextTick(() => {
                swagger = SwaggerUI({
                    docExpansion: 'list',
                    dom_id: '#swagger',
                    url: "api",
                    plugins: [
                        StandalonePreset,
                    ],
                    layout: 'StandaloneLayout',
                    requestInterceptor: req => {
                        req.headers['Authorization'] = 'Bearer ' + getProfile().jwt
                    },
                })  
                swagger.preauthorizeApiKey("Bearer", getProfile().jwt)
            })
        },
</script>

Do I have to use swagger-ui-react instead?

Was this page helpful?
0 / 5 - 0 ratings