sourcefuse / loopback4-starter

Loopback 4 starter application. Multi-tenant architecture supported. Authentication, Authorization, Soft deletes, environment vars, Audit logs, included.
MIT License
158 stars 59 forks source link

malformed array literal upon posting a role #19

Closed sherif2011 closed 5 years ago

sherif2011 commented 5 years ago

Hello,

When I try creating a new role through Postman, I get a 500 and below error. Any clue, does postgres/repository have an issue storing the passed array of strings (permissions)?

{ "deleted": true, "createdOn": "2019-07-16T15:30:29.847Z", "modifiedOn": "2019-07-16T15:30:29.847Z", "name": "roletest", "permissions": [ "test" ], "roleKey": 5 }

Unhandled error in POST /roles: 500 error: malformed array literal: "["test"]" at Connection.parseE (C:\Users\smankarious\Desktop\admin\node_modules\pg\lib\connection.js:601:11) at Connection.parseMessage (C:\Users\smankarious\Desktop\admin\node_modules\pg\lib\connection.js:398:19) at Socket. (C:\Users\smankarious\Desktop\admin\node_modules\pg\lib\connection.js:120:22) at Socket.emit (events.js:198:13) at addChunk (_stream_readable.js:288:12) at readableAddChunk (_stream_readable.js:269:11) at Socket.Readable.push (_stream_readable.js:224:10) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)

Thanks,

sherif2011 commented 5 years ago

I am seeing links talking about loopback-connector-postgresql not supporting arrays link Is that still an issue? Should I convert to string?

samarpan-b commented 5 years ago

Hello @sherif2011 , Unfortunately yes, there is an open issue with loopback-connector-postgresql that array types cannot be saved via this. However, find methods can work.

We actually created our own overridden methods in repository for such operations.

Consider a model Cpw with two array type columns majors and minors, below is how we solved it in cpw-repository.ts.

async create(entity: DataObject<Cpw>, options?: Options): Promise<Cpw> {
    const majors = `{${entity.majors ? entity.majors.join() : ''}}`;
    const minors = `{${entity.minors ? entity.minors.join() : ''}}`;

     const query = `INSERT INTO public.cpw(
      majors, minors, name, "desc", read_more_link)
      VALUES ('${majors}', '${minors}', '${entity.name}', '${entity.desc ||
      ''}', '${entity.readMoreLink || ''}')`;
    await super.execute(query, []);
    return (await this.findOne({
      order: ['createdBy DESC'],
    })) as Cpw;
  }
  async updateById(id: number, entity: DataObject<Cpw>): Promise<void> {
    const majors = `{${entity.majors ? entity.majors.join() : ''}}`;
    const minors = `{${entity.minors ? entity.minors.join() : ''}}`;

     const query = `UPDATE public.cpw SET
       majors='${majors}', minors= '${minors}', name='${
      entity.name
    }',"desc"='${entity.desc || ''}',read_more_link='${entity.readMoreLink ||
      ''}' WHERE id=${id}`;
    await super.execute(query, []);
  }

Hope this helps.

sherif2011 commented 5 years ago

Worked like a charm. Thanks samarpan-b !!