Guido
Guido

Reputation: 81

Loopback.js - How do I pass multiple parameters to model remote method

I'm trying to change a remote method for the Idioma model which only had one parameter (id). This is is the actual functioning code:

Model.remoteMethod('idiomaByOferta', {
  description: 'Obtener un idioma por oferta',
  http: { path: '/oferta/:id', verb: 'get' },
  accepts: [
    { arg: 'id', type: 'string', required: true },
    { arg: 'res', type: 'object', http: { source: 'res' } }
  ],
  returns: {
    type: 'Object',
    root: true,
    default: output_structure
  }
});

Model.idiomaByOferta = (id, res, cb) => {
  parameterValidatorId(id, err => {
    if (err) {
      res.status(httpStatus.BAD_REQUEST.code).send(err);
    }
  });
  const conn = Model.app.datasources.db.connector;
  commons
    .getResultSqlString(conn, sqlEstablecimiento.findIdiomas, [id])
    .then(stb => {
      cb(null, stb);
    })
    .catch(err => cb(err, null));
  };

Model.afterRemote('idiomaByOferta', async (ctx, result, next) => {
  delete ctx.res.req.query.limit;
  delete ctx.res.req.query.page;
  delete query.limit;
  delete query.page;
  next();
});

Now I want to include another parameter but I haven't found exactly how to do it with required parameters. I have tried the following but it doesn't work:

Model.remoteMethod('idiomaByOferta', {
  description: 'Obtener un idioma por oferta',
  http: { path: '/oferta', verb: 'get' },
  accepts: [
    { arg: 'id', type: 'string', required: true, http: { source: 'query' }},
    { arg: 'nivel', type: 'string', required: true, http: { source: 'query' }},
    { arg: 'res', type: 'object', http: { source: 'res' } }
  ],
  returns: {
    type: 'Object',
    root: true,
    default: output_structure
  }
});

Request url: {{url}}/api/idiomas/oferta?id={{oferta}}&nivel=Inicial

Response:

{
    "errors": [
        {
            "code": 938,
            "source": "id",
            "detail": "is not allowed"
        },
        {
            "code": 963,
            "source": "nivel",
            "detail": "is not allowed"
        }
    ]
}

I have also tried doing this:

Model.remoteMethod('idiomaByOferta', {
  description: 'Obtener un idioma por oferta',
  http: { path: '/oferta/:id/nivel/:nivel', verb: 'get' },
  accepts: [
    { arg: 'id', type: 'string', required: true},
    { arg: 'nivel', type: 'string', required: true},
    { arg: 'res', type: 'object', http: { source: 'res' } }
  ],
  returns: {
    type: 'Object',
    root: true,
    default: output_structure
  }
});

The request times out and is never completed.

Upvotes: 0

Views: 1193

Answers (1)

F3L1X79
F3L1X79

Reputation: 2675

The position of your accepts attributes is important.

In your http attribute, the argument path is optionnal and is useful if you want to change the order of your accepts attributes or simply modify the path name.

What I would do is:

Model.remoteMethod('idiomaByOferta', {
  description: 'Obtener un idioma por oferta',
  http: { path: '/oferta/:id/:nivel', verb: 'get' },
  accepts: [
    { arg: 'id', type: 'string', required: true },
    { arg: 'nivel', type: 'string', required: true},
    { arg: 'res', type: 'object', http: { source: 'res' } }
  ],
  returns: {
    type: 'Object',
    root: true,
    default: output_structure
  }
});

Model.idiomaByOferta = (id, nivel, res, cb) => { //add nivel here in second position
  parameterValidatorId(id, err => {
    if (err) {
      res.status(httpStatus.BAD_REQUEST.code).send(err);
    }
  });
  parameterValidatorId(nivel, err => {
    if (err) {
      res.status(httpStatus.BAD_REQUEST.code).send(err);
    }
  });
  const conn = Model.app.datasources.db.connector;
  commons
    .getResultSqlString(conn, sqlEstablecimiento.findIdiomas, [id, nivel]) //and use it there, maybe, depending on what your code is doing?
    .then(stb => {
      cb(null, stb);
    })
    .catch(err => cb(err, null));
  };

Upvotes: 1

Related Questions