create-client icon indicating copy to clipboard operation
create-client copied to clipboard

TypeError: Cannot read property 'properties' of undefined

Open flyfishMT opened this issue 6 years ago • 7 comments

Hi, I am trying to generate a react client from a swagger API.

npx @api-platform/client-generator http:/myapi/swagger/docs/v1 src/ --resource Item --format swagger

I get the error

TypeError: Cannot read property 'properties' of undefined

I stepped through this a little and this error occurs here:

exports.default = function (response, entrypointUrl) {
  var paths = (0, _lodash.uniq)((0, _keys2.default)(response.paths).map(function (item) {
    return item.replace("/{id}", "");
  }));

  var resources = paths.map(function (item) {
    var name = item.replace("/", "");
    var url = removeTrailingSlash(entrypointUrl) + item;
    var firstMethod = (0, _keys2.default)(response.paths[item])[0];
    var title = response.paths[item][firstMethod]["tags"][0];
    /* 
     * ERROR OCCURS HERE:
     */
    var fieldNames = (0, _keys2.default)(response.definitions[title].properties);

What happens, is it attempts to get fieldNames from

var title = response.paths[item][firstMethod]["tags"][0]; // tags[0] = "Item"
response.definitions["Item"].properties.

However, the Item endpoint does not return an Item object, it returns "ApiResponse[ItemDto]".

"paths": {

    "/api/v1/Item": {
      "get": {
        "tags": [
          "Item"
        ],
        ....
        "parameters": [
	....
        ],

        "responses": {
          "200": {
            "description": "OK",
            "schema": {
              "$ref": "#/definitions/ApiResponse[ItemDto]"
            }
          }
        }
      },
},
"definitions": {
"ApiResponse[ItemDto]": {
      "type": "object",
      "properties": {
        "Pagination": {
          "$ref": "#/definitions/ApiPagination"
        },
        "Data": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/ItemDto"
          }
        }
      }
    },

So I can see that to find the properties it needs to traverse the "$ref's".

Any advice would be appreciated.

flyfishMT avatar Jan 25 '19 17:01 flyfishMT

Note, this is actually occurring in api-doc-parser, I probably should have created the issue there. Thanks

flyfishMT avatar Jan 25 '19 17:01 flyfishMT

And response.definitions[title].required does not exists in my swagger API.

...
required: !!response.definitions[title].required.find(function (value) {
          return value === fieldName;
        }),
...

The above triggers error because it cannot call method find() on undefined

gusarov112 avatar Feb 12 '19 16:02 gusarov112

@gusarov112 thanks for investigating! Would you mind to provide a PR to fix this?

dunglas avatar Feb 12 '19 17:02 dunglas

@dunglas Sorry, but I don't know whether this is API problem, or generator problem? Maybe I should fix my API somehow? But of course, it would be better to create a response.definition object structure with defaults, and hydrate response.definition with not existing but required sub-resources with dummy structured object. So you don't need checks on undefined.

gusarov112 avatar Feb 13 '19 12:02 gusarov112

Even if the generated doc isn't valid (we need to investigate this too), the client library should not fail anyway ("Be conservative in what you send, be liberal in what you accept"). So we need to patch the client library at least.

dunglas avatar Feb 13 '19 12:02 dunglas

I'm at the moment running in the same issue.

Cruiser13 avatar Sep 04 '19 15:09 Cruiser13

i get a quickly sulution updating the file .../@api-platform\api-doc-parser\lib\swagger\handleJson.js

    // var title = response.paths[item][firstMethod]["tags"][0];
    var title = '';
    var fields = []

    try {
      title = response.paths[item][firstMethod]["parameters"][0]["schema"]["$ref"].replace("#/definitions/", "");

      var fieldNames = (0, _keys2.default)(response.definitions[title].properties);

      fields = fieldNames.map(function (fieldName) {
        return new _Field2.default(fieldName, {
          id: null,
          range: null,
          reference: null,
          required: response.definitions[title].required && !!response.definitions[title].required.find(function (value) {
            return value === fieldName;
          }),
          description: (0, _lodash2.default)(response.definitions[title].properties[fieldName], "description", "")
        });
      });
    } catch (error) {
      console.log(response.paths[item][firstMethod], item, firstMethod)
    }

lucasfontesgaspareto avatar Sep 27 '19 15:09 lucasfontesgaspareto

OpenAPI 3 support has been greatly improved in the client generator (and the underlying library) since https://github.com/api-platform/api-doc-parser/pull/108. There should no be major issue now.

alanpoulain avatar Aug 23 '22 13:08 alanpoulain