json-api icon indicating copy to clipboard operation
json-api copied to clipboard

andWhere query is not working

Open sohamdodia opened this issue 5 years ago • 11 comments

andWhere query is throwing an error: Errors converted to json-api Result TypeError: Cannot read property '0' of undefined.

   
queryFactory: async (opts) => {
      const origQuery = await opts.makeQuery(opts);
      return origQuery.andWhere({ field: "user_name", operator: "eq", value: "somename" });
    }


I have also downloaded the example provided in https://github.com/ethanresnick/json-api-example/tree/v3-wip repo, but the same error has occurred in this example as well.

sohamdodia avatar Nov 07 '19 16:11 sohamdodia

Can you provide a full stack trace for the error? This really isn't enough to debug with...

ethanresnick avatar Nov 07 '19 20:11 ethanresnick

Errors converted to json-api Result TypeError: Cannot read property '0' of undefined at toMongoCriteria (/json-api-example-3-wip/node_modules/json-api/build/src/db-adapters/Mongoose/lib.js:71:38) at Array.map () at Object.toMongoCriteria (/json-api-example-3-wip/node_modules/json-api/build/src/db-adapters/Mongoose/lib.js:62:50) at MongooseAdapter. (/json-api-example-3-wip/node_modules/json-api/build/src/db-adapters/Mongoose/MongooseAdapter.js:63:43) at Generator.next () at /json-api-example-3-wip/node_modules/json-api/build/src/db-adapters/Mongoose/MongooseAdapter.js:7:71 at new Promise () at __awaiter (/json-api-example-3-wip/node_modules/json-api/build/src/db-adapters/Mongoose/MongooseAdapter.js:3:12) at MongooseAdapter.find (/json-api-example-3-wip/node_modules/json-api/build/src/db-adapters/Mongoose/MongooseAdapter.js:59:16) at Object.runQuery [as default] (/json-api-example-3-wip/node_modules/json-api/build/src/steps/run-query.js:28:19) at Object.APIController.runQuery (/json-api-example-3-wip/node_modules/json-api/build/src/controllers/API.js:58:55) at /json-api-example-3-wip/node_modules/json-api/build/src/controllers/API.js:227:43 at Generator.next () at fulfilled (/json-api-example-3-wip/node_modules/json-api/build/src/controllers/API.js:4:58)

sohamdodia avatar Nov 08 '19 16:11 sohamdodia

@sohamdodia Does this error only occur when using AWS Serverless, or are you also experiencing it locally?

ethanresnick avatar Nov 08 '19 18:11 ethanresnick

This issue is also occurring with local server as well.

sohamdodia avatar Nov 08 '19 18:11 sohamdodia

@sohamdodia Can you paste a log of the opts object that your query factory function is receiving, and a log of the origQuery variable

ethanresnick avatar Nov 08 '19 18:11 ethanresnick

@ethanresnick if you send me an email to [email protected] id be happy to set up a contract to help us get this library working with serverless and solve this issue (and of course assume any code updates/docs would be shared open source)

emac08 avatar Nov 08 '19 18:11 emac08

opts object:

{ request:
   { queryParams: { filter: undefined, sort: undefined },
     rawQueryString: undefined,
     id: undefined,
     type: 'media',
     relationship: undefined,
     aboutRelationship: false,
     uri: 'https://localhost/media',
     method: 'get',
     accepts: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
     contentType: undefined,
     body: undefined,
     document: undefined },
  registry:
   ResourceTypeRegistry {
     _errorsConfig: undefined,
     _types:
      { todos: Map { "transformLinkage": false, "pagination": Map {}, "dbAdapter": [object Object], "urlTemplates": Map { "self": function (context) {
        return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) {
          if (expression) {
            var operator = null,
                values = [];

            if (operators.indexOf(expression.charAt(0)) !== -1) {
              operator = expression.charAt(0);
              expression = expression.substr(1);
            }

            expression.split(/,/g).forEach(function (variable) {
              var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable);
              values.push.apply(values, that.getValues(context, operator, tmp[1], tmp[2] || tmp[3]));
            });

            if (operator && operator !== '+') {
              var separator = ',';

              if (operator === '?') {
                separator = '&';
              } else if (operator !== '#') {
                separator = operator;
              }
              return (values.length !== 0 ? operator : '') + values.join(separator);
            } else {
              return values.join(',');
            }
          } else {
            return that.encodeReserved(literal);
          }
        });
      }, "relationship": function (context) {
        return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) {
          if (expression) {
            var operator = null,
                values = [];

            if (operators.indexOf(expression.charAt(0)) !== -1) {
              operator = expression.charAt(0);
              expression = expression.substr(1);
            }

            expression.split(/,/g).forEach(function (variable) {
              var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable);
              values.push.apply(values, that.getValues(context, operator, tmp[1], tmp[2] || tmp[3]));
            });

            if (operator && operator !== '+') {
              var separator = ',';

              if (operator === '?') {
                separator = '&';
              } else if (operator !== '#') {
                separator = operator;
              }
              return (values.length !== 0 ? operator : '') + values.join(separator);
            } else {
              return values.join(',');
            }
          } else {
            return that.encodeReserved(literal);
          }
        });
      } } },
        notes: Map { "transformLinkage": false, "pagination": Map {}, "dbAdapter": [object Object], "urlTemplates": Map { "self": function (context) {
        return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) {
          if (expression) {
            var operator = null,
                values = [];

            if (operators.indexOf(expression.charAt(0)) !== -1) {
              operator = expression.charAt(0);
              expression = expression.substr(1);
            }

            expression.split(/,/g).forEach(function (variable) {
              var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable);
              values.push.apply(values, that.getValues(context, operator, tmp[1], tmp[2] || tmp[3]));
            });

            if (operator && operator !== '+') {
              var separator = ',';

              if (operator === '?') {
                separator = '&';
              } else if (operator !== '#') {
                separator = operator;
              }
              return (values.length !== 0 ? operator : '') + values.join(separator);
            } else {
              return values.join(',');
            }
          } else {
            return that.encodeReserved(literal);
          }
        });
      }, "relationship": function (context) {
        return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) {
          if (expression) {
            var operator = null,
                values = [];

            if (operators.indexOf(expression.charAt(0)) !== -1) {
              operator = expression.charAt(0);
              expression = expression.substr(1);
            }

            expression.split(/,/g).forEach(function (variable) {
              var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable);
              values.push.apply(values, that.getValues(context, operator, tmp[1], tmp[2] || tmp[3]));
            });

            if (operator && operator !== '+') {
              var separator = ',';

              if (operator === '?') {
                separator = '&';
              } else if (operator !== '#') {
                separator = operator;
              }
              return (values.length !== 0 ? operator : '') + values.join(separator);
            } else {
              return values.join(',');
            }
          } else {
            return that.encodeReserved(literal);
          }
        });
      } } },
        media: Map { "transformLinkage": false, "pagination": Map {}, "dbAdapter": [object Object], "urlTemplates": Map { "self": function (context) {
        return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) {
          if (expression) {
            var operator = null,
                values = [];

            if (operators.indexOf(expression.charAt(0)) !== -1) {
              operator = expression.charAt(0);
              expression = expression.substr(1);
            }

            expression.split(/,/g).forEach(function (variable) {
              var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable);
              values.push.apply(values, that.getValues(context, operator, tmp[1], tmp[2] || tmp[3]));
            });

            if (operator && operator !== '+') {
              var separator = ',';

              if (operator === '?') {
                separator = '&';
              } else if (operator !== '#') {
                separator = operator;
              }
              return (values.length !== 0 ? operator : '') + values.join(separator);
            } else {
              return values.join(',');
            }
          } else {
            return that.encodeReserved(literal);
          }
        });
      }, "relationship": function (context) {
        return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) {
          if (expression) {
            var operator = null,
                values = [];

            if (operators.indexOf(expression.charAt(0)) !== -1) {
              operator = expression.charAt(0);
              expression = expression.substr(1);
            }

            expression.split(/,/g).forEach(function (variable) {
              var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable);
              values.push.apply(values, that.getValues(context, operator, tmp[1], tmp[2] || tmp[3]));
            });

            if (operator && operator !== '+') {
              var separator = ',';

              if (operator === '?') {
                separator = '&';
              } else if (operator !== '#') {
                separator = operator;
              }
              return (values.length !== 0 ? operator : '') + values.join(separator);
            } else {
              return values.join(',');
            }
          } else {
            return that.encodeReserved(literal);
          }
        });
      } } } },
     _typesMetadata: { nodes: [Array], edges: {}, roots: [Array] } },
  serverReq:
   IncomingMessage {
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: BufferList { length: 0 },
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: true,
        ended: true,
        endEmitted: true,
        reading: false,
        errorEmitted: false,
        sync: true,
        needReadable: false,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        emitClose: true,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: true,
        decoder: null,
        encoding: null },
     readable: false,
     domain: null,
     _events: {},
     _eventsCount: 0,
     _maxListeners: undefined,
     socket:
      { encrypted: true,
        readable: false,
        remoteAddress: '127.0.0.1',
        address: [Function: address],
        end: [Function],
        destroy: [Function] },
     connection:
      { encrypted: true,
        readable: false,
        remoteAddress: '127.0.0.1',
        address: [Function: address],
        end: [Function],
        destroy: [Function] },
     httpVersionMajor: '1',
     httpVersionMinor: '1',
     httpVersion: '1.1',
     complete: true,
     headers:
      { host: 'localhost:8080',
        connection: 'keep-alive',
        'cache-control': 'max-age=0',
        'upgrade-insecure-requests': '1',
        'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36',
        'sec-fetch-user': '?1',
        accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
        'sec-fetch-site': 'none',
        'sec-fetch-mode': 'navigate',
        'accept-encoding': 'gzip, deflate, br',
        'accept-language': 'en-US,en;q=0.9',
        cookie: '_ga=GA1.1.182961221.1554040199; token=77eb5c36-9438-4303-8bbd-fdd6cb4ab8c5',
        'if-none-match': 'W/"6c9-sf4l2A9UsRGuIrLzxbG0g4TrLVo"',
        'x-request-id': 'offlineContext_requestId_ck2qikym40001jdrmeslb86v3',
        'content-length': 0 },
     rawHeaders: [],
     trailers: {},
     rawTrailers: [],
     upgrade: null,
     url: '/media',
     method: 'GET',
     statusCode: null,
     statusMessage: null,
     client:
      { encrypted: true,
        readable: false,
        remoteAddress: '127.0.0.1',
        address: [Function: address],
        end: [Function],
        destroy: [Function] },
     _consuming: false,
     _dumped: false,
     ip: '127.0.0.1',
     body: <Buffer >,
     requestContext:
      { accountId: 'offlineContext_accountId',
        apiId: 'offlineContext_apiId',
        authorizer: [Object],
        httpMethod: 'GET',
        identity: [Object],
        protocol: 'HTTP/1.1',
        requestId: 'offlineContext_requestId_ck2qikym40001jdrmeslb86v3',
        requestTimeEpoch: 1573240173998,
        resourceId: 'offlineContext_resourceId',
        resourcePath: '/media',
        stage: 'dev' },
     serverless: { event: [Object], context: [LambdaContext] },
     next: [Function: next],
     baseUrl: '',
     originalUrl: '/media',
     _parsedUrl:
      Url {
        protocol: null,
        slashes: null,
        auth: null,
        host: null,
        port: null,
        hostname: null,
        hash: null,
        search: null,
        query: null,
        pathname: '/media',
        path: '/media',
        href: '/media',
        _raw: '/media' },
     params: { type: 'media' },
     query: {},
     res:
      ServerResponse {
        domain: null,
        _events: [Object],
        _eventsCount: 2,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: false,
        chunkedEncoding: false,
        shouldKeepAlive: true,
        useChunkedEncodingByDefault: false,
        sendDate: true,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: null,
        _hasBody: true,
        _trailer: '',
        finished: false,
        _headerSent: false,
        socket: [Writable],
        connection: [Writable],
        _header: null,
        _onPendingData: [Function: noopPendingOutput],
        _sent100: false,
        _expect_continue: false,
        write: [Function],
        req: [Circular],
        locals: {},
        _startAt: undefined,
        _startTime: undefined,
        writeHead: [Function: writeHead],
        __onFinished: [Function],
        [Symbol(isCorked)]: false,
        [Symbol(outHeadersKey)]: [Object],
        [Symbol()]: [],
        [Symbol()]: {} },
     _startAt: [ 1119449, 442403521 ],
     _startTime: 2019-11-08T19:09:40.413Z,
     _remoteAddress: '127.0.0.1',
     route: Route { path: '/:type(media)', stack: [Array], methods: [Object] } },
  serverRes:
   ServerResponse {
     domain: null,
     _events: { end: [Array], finish: [Array] },
     _eventsCount: 2,
     _maxListeners: undefined,
     output: [],
     outputEncodings: [],
     outputCallbacks: [],
     outputSize: 0,
     writable: true,
     _last: false,
     chunkedEncoding: false,
     shouldKeepAlive: true,
     useChunkedEncodingByDefault: false,
     sendDate: true,
     _removedConnection: false,
     _removedContLen: false,
     _removedTE: false,
     _contentLength: null,
     _hasBody: true,
     _trailer: '',
     finished: false,
     _headerSent: false,
     socket:
      Writable {
        _writableState: [WritableState],
        writable: true,
        _write: [Function: write],
        domain: null,
        _events: [Object],
        _eventsCount: 2,
        _maxListeners: undefined,
        _httpMessage: [Circular] },
     connection:
      Writable {
        _writableState: [WritableState],
        writable: true,
        _write: [Function: write],
        domain: null,
        _events: [Object],
        _eventsCount: 2,
        _maxListeners: undefined,
        _httpMessage: [Circular] },
     _header: null,
     _onPendingData: [Function: noopPendingOutput],
     _sent100: false,
     _expect_continue: false,
     write: [Function],
     req:
      IncomingMessage {
        _readableState: [ReadableState],
        readable: false,
        domain: null,
        _events: {},
        _eventsCount: 0,
        _maxListeners: undefined,
        socket: [Object],
        connection: [Object],
        httpVersionMajor: '1',
        httpVersionMinor: '1',
        httpVersion: '1.1',
        complete: true,
        headers: [Object],
        rawHeaders: [],
        trailers: {},
        rawTrailers: [],
        upgrade: null,
        url: '/media',
        method: 'GET',
        statusCode: null,
        statusMessage: null,
        client: [Object],
        _consuming: false,
        _dumped: false,
        ip: '127.0.0.1',
        body: <Buffer >,
        requestContext: [Object],
        serverless: [Object],
        next: [Function: next],
        baseUrl: '',
        originalUrl: '/media',
        _parsedUrl: [Url],
        params: [Object],
        query: {},
        res: [Circular],
        _startAt: [Array],
        _startTime: 2019-11-08T19:09:40.413Z,
        _remoteAddress: '127.0.0.1',
        route: [Route] },
     locals: {},
     _startAt: undefined,
     _startTime: undefined,
     writeHead: [Function: writeHead],
     __onFinished: { [Function: listener] queue: [Array] },
     [Symbol(isCorked)]: false,
     [Symbol(outHeadersKey)]:
      { 'x-powered-by': [Array],
        'access-control-allow-origin': [Array] },
     [Symbol()]: [],
     [Symbol()]: {} },
  makeDocument: [Function],
  beforeSave: [Function],
  beforeRender: [Function],
  transformDocument: [Function: transformDocument],
  makeQuery: [Function: makeQuery],
  runQuery: [Function],
  setTypePaths: [Function: setTypePaths] }

OrigQuery: {"query":{"type":"media","criteria":{"where":{"type":"FieldExpression","operator":"and","args":[{"field":"user_name","operator":"eq","value":"somename"}]},"isSingular":false},"populates":[],"ignoreLimitMax":false}}

sohamdodia avatar Nov 08 '19 19:11 sohamdodia

+1

gabrielsperezz avatar Jan 22 '20 19:01 gabrielsperezz

In the example repository it also doesn't work. Link: https://github.com/ethanresnick/json-api-example/blob/dc4e02710b2debce0ad5f9e6e3f0514dcc6b7831/src/index.js#L61

gabrielsperezz avatar Jan 22 '20 20:01 gabrielsperezz

@sohamdodia, @emac08, and others in this thread... sorry for my non-responsiveness here. I went traveling shortly after this issue was reported and was not at a computer for a couple weeks; when I got back, life intervened hard. Did any of you figure out the cause of this issue (if you stuck with this library)? If so, I'd love to hear it and to incorporate a fix.

ethanresnick avatar Jan 24 '20 06:01 ethanresnick

@ethanresnick This is still happening, even in the example. Is this library maintained? I am starting to wonder whether I should use it.

amitassaraf avatar Mar 08 '20 00:03 amitassaraf