swagger-ui icon indicating copy to clipboard operation
swagger-ui copied to clipboard

swagger-ui-react getting "TypeError: Object(...) is not a function" on POST, PUT, or DELETE

Open leeperkins opened this issue 3 years ago • 16 comments

Q&A (please complete the following information)

  • OS: Windows 10
  • Browser: Edge, Chrome, Firefox
  • Version: Lastest browser versions as of 25-Jan-2022 @ 11:30AM EST
  • Method of installation: npm install swagger-ui-react
  • Swagger-UI version: 4.3.0
  • Swagger/OpenAPI version: Don't know?

Content & configuration

Since I'm using webpack 5, I had to add polyfills for stream and buffer in webpack.config.js:

const webpack = require('webpack');
...
, plugins: [
  ...
  , new webpack.ProvidePlugin({
    Buffer: ["buffer", "Buffer"]
  })
]
, resolve: {
    ...
    , fallback: {
      stream: require.resolve("stream-browserify")
      , buffer: require.resolve("buffer")
    }
}

The html file:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Issuetrak API v2</title>
    <script src="core/Scripts/require.js" data-main="core/Scripts/swagger/app"></script>
</head>

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

The entry .tsx:

import * as ReactDOM from "react-dom";
import React from "react";
import SwaggerUI from "swagger-ui-react";
import "swagger-ui-react/swagger-ui.css";

const swaggerElement = document.querySelector("#swagger-ui");
if (swaggerElement) {
    ReactDOM.render(
        <SwaggerUI
            url="api/v2/swagger/v2/swagger.json"
        />
        , swaggerElement
    );
}

Describe the bug you're encountering

The swagger page is loading just fine, and displays all our end points. When I click the [Try it out] button for an endpoint that is POST, PUT, or DELETE, and fill in any parameters and click the [Execute] button, I get the following error in the console and no network request is made.

TypeError: Object(...) is not a function
    at Object.nn [as execute] (swagger-ui.js:2214:330)
    at swagger-ui.js:315:160
    at Object.dispatch (swagger-ui.js:36:687)
    at dispatch (<anonymous>:10608:80)
    at redux.js:469:1
    at swagger-ui.js:1228:375
    at Object.r (swagger-ui.js:3815:414)
    at Object.executeRequest (swagger-ui.js:3859:1)
    at swagger-ui.js:315:1041
    at Object.dispatch (swagger-ui.js:36:687)

GET api end points work fine.

To reproduce...

Steps to reproduce the behavior: You can try setting up the same scenario I have. The relevant webpack.config.js as well as .html and entry .tsx are listed above, change the url="..." in the .tsx to a valid swagger.json. No idea if it will recreate the bug outside of my development environment and with a different api.

Navigate to the the .html file, expand a "POST", "PUT", or "DELETE" endpoint, click [Try it out], fill in any relevant parameters, click [Execute], see the error in the developer tools console.

Expected behavior

When I click [Execute], I expect a network call to the api endpoint to be made and no JavaScript error in the developer tools console.

Screenshots

image

Additional context or thoughts

Our normal swagger page is working fine. It's accessed via the url api/v2/swagger/index.html and is configured in our c# code using Swashbuckle UI. This new swagger page we're trying to get working will be accessed just by apiv2.swagger.html (from the root of the site, not from api/v2/swagger) and loads a react app via a <script src="core/Scripts/require.js" data-main="core/Scripts/swagger/app"></script> tag. The reason we're doing this is so we can add our menuing framework (left and right side menus, and a top-bar) around the swagger ui. Our menu components are all React.

leeperkins avatar Jan 25 '22 18:01 leeperkins

Hi @leeperkins, is this still manifesting in version [email protected]?

char0n avatar Jan 27 '22 08:01 char0n

It is. I was getting a different error before, then I noticed (at the time) that 3 hours earlier a fix for the bug I was having had just been merged and I updated to 4.3.0. Then I was getting this error. I've since changed over to using swagger-ui instead of swagger-ui-react and it's working just fine (injecting it in React as below). I'd still be interested in using the React version if I could get it working though.

    public render(): JSX.Element {
        return <>
            <div id="mainContent">
                <div id="main-content-scroll">
                    <div id="swagger-ui"></div>
                </div>
            </div>
        </>;
    }

    public componentDidMount(): void {
        SwaggerUI({
            url: "api/v2/swagger/v2/swagger.json"
            , dom_id: "#swagger-ui"
        });
    }

leeperkins avatar Jan 27 '22 12:01 leeperkins

Hello

we are having this exact error using 4.4.0 or 4.3.0 MicrosoftTeams-image (2)

anyone found a solution? Thanks!

hvaleanu avatar Jan 27 '22 12:01 hvaleanu

Same issue happens when swagger-ui is rendered through the latest backstage setup. There it is resolved as swagger-ui-react 4.4.1.

PavelPolyakov avatar Feb 02 '22 15:02 PavelPolyakov

@PavelPolyakov 4.4.1 comes with following fix: https://github.com/swagger-api/swagger-ui/commit/6c10e4a0701d5076afa69d6fd1c87bea872ec096 which patches a feature introduced in 4.4.0, so I don't see how the 4.4.1 would resolve this issue.

char0n avatar Feb 02 '22 21:02 char0n

@char0n yes, I've left my comment to mention other impact of this behaviour - backstage.

May I ask if the reason of this behaviour is known, is this considered as bug or still triaging?

PavelPolyakov avatar Feb 03 '22 09:02 PavelPolyakov

It's obviously a bug and most definitely not only in swagger-ui-react but also in swagger-ui. Feel free to investigate and provide a bugfix. At least investigation why this happens would help a lot.

char0n avatar Feb 03 '22 10:02 char0n

This seems to be still an issue in 4.5.0

NoobSkywalker avatar Feb 14 '22 16:02 NoobSkywalker

Tried to dig a bit but not sure how this is exactly constructed. Issue seems here: image So it seems there might be some issue with webpack and the is-plain-object version? can't clearly figure out why though

NoobSkywalker avatar Feb 14 '22 17:02 NoobSkywalker

Ok, so after some more digging it seems that the is-plain-object module used in swagger-client (changed here: https://github.com/swagger-api/swagger-js/commit/067229e8f7d6b55a68cb62278a662fc2a97c9f0a) is picking up an old version as its part of @babel#register#clone-deep and webpack includes it as well...

NoobSkywalker avatar Feb 14 '22 21:02 NoobSkywalker

what seemed to help in my case is to install is-plain-object as dependency in my project. Somehow webpack seems to then properly pick it up.

NoobSkywalker avatar Feb 14 '22 21:02 NoobSkywalker

@NoobSkywalker thanks for the investigation 🙇‍♂️

PavelPolyakov avatar Feb 15 '22 09:02 PavelPolyakov

the workaround is-plain-object worked!

I found that the TypeError: Object(...) is not a function only happens when swagger is trying to preprocess the request that has a JSON (application/JSON) payload.

For those requests that pure path parameters, this issues does not happen.

Hope this helps.

vchoy avatar Mar 10 '22 10:03 vchoy

@NoobSkywalker thank you!!!!!

I installed is-plain-object and now it works. Thanks a lot!

mauretto78 avatar Mar 17 '22 12:03 mauretto78

The workaround with is-plain-object did not work for me, still getting the same error when Trying Out a POST request with body JSON payload obraz

Update: After updating to 4.6.2 and installing is-plain-object 5.0.0 as my project dependency, the error is gone.

It seems to be a "lost in trans(pi)lation" problem as the swagger-client properly imports { isPlainObject } from 'is-plain-object'; in execute, but it's somehow improperly transpiled. swagger-client does if (request.body && (isPlainObject(request.body) ... but it becomes if (request.body && ((0,external_is_plain_object_namespaceObject.isPlainObject)(request.body) ... So it seems to be what @NoobSkywalker said that it's picking up the wrong version.

wlechowicz avatar Mar 20 '22 01:03 wlechowicz

Just commenting here for anyone else who has encountered this error with FastAPI.

I was able to apply a polyfill into my swagger-ui-bundle.js for any objects that do not have a .hasOwn.

By placing the below inside my swagger-ui-bundle.js - my error has seem to go away.

if (!Object.hasOwn) {
    Object.hasOwn = function(obj, prop) {
        return Object.prototype.hasOwnProperty.call(obj, prop);
    };
}

Hope this helps - and would love some feedback incase this creates any unknown side effects.

AlexScotland avatar Sep 06 '24 18:09 AlexScotland