Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

why Loopback + mongodb is not working? #3645

Closed
rsa408 opened this issue Sep 3, 2019 · 8 comments · Fixed by #3667
Closed

why Loopback + mongodb is not working? #3645

rsa408 opened this issue Sep 3, 2019 · 8 comments · Fixed by #3667
Assignees
Labels
db:MongoDB Topics specific to MongoDB

Comments

@rsa408
Copy link

rsa408 commented Sep 3, 2019

Hi guys,

it is 5 day that I try to start lb4 with MongoDB all the movies and tutorials I looked at the net but my problem was solved. I made git repo and uploaded a very basic code.https://github.com/RsaLB4/test

I will be appreciated if you can help me.
screenshots also are there.

Great thanks

The steps I have followed to create project:

C:>lb4 test
? Project description: test
? Project root directory: test
? Application class name: TestApplication
? Select features to enable in the project (Press <space> to select, <a> to toggle all, <i> to invert selection)Enable eslint, Enable prettier, Enable mocha, Enable loopbackBuild, Enable vscode, Enable docker, Enable repositories, Enable services

   create .eslintignore
   create .eslintrc.js
   create .mocharc.json
   create .npmrc
   create .prettierignore
   create .prettierrc
   create DEVELOPING.md
   create index.ts
   create package.json
   create README.md
   create tsconfig.json
   create .vscode\settings.json
   create .vscode\tasks.json
   create .gitignore
   create .dockerignore
   create Dockerfile
   create index.js
   create public\index.html
   create src\application.ts
   create src\index.ts
   create src\migrate.ts
   create src\sequence.ts
   create src\controllers\index.ts
   create src\controllers\ping.controller.ts
   create src\controllers\README.md
   create src\datasources\README.md
   create src\models\README.md
   create src\repositories\README.md
   create src_tests_\README.md
   create src_tests_\acceptance\home-page.acceptance.ts
   create src_tests_\acceptance\ping.controller.acceptance.ts
   create src_tests_\acceptance\test-helper.ts

npm WARN deprecated [email protected]: Please note that v5.0.1+ of superagent removes User-Agent header by default, therefore you may need to add it yourself (e.g. GitHub blocks requests without a User-Agent header).  This notice will go away with v5.0.2+ once it is released.

[email protected] postinstall C:\test\node_modules\core-js
node scripts/postinstall || echo "ignore"
Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!
The project needs your help! Please consider supporting of core-js on Open Collective or Patreon:

https://opencollective.com/core-js
https://www.patreon.com/zloirock

Also, the author of core-js ( https://github.com/zloirock ) is looking for a good job -)
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN [email protected] No license field.
added 529 packages from 1195 contributors and audited 3946 packages in 78.055s
found 0 vulnerabilities

Application test was created in test.

Next steps:
$ cd test
$ npm start

C:>cd test
C:\test>lb4 datasource
? Datasource name: mongoDS
? Select the connector for mongoDS: MongoDB (supported by StrongLoop)
? Connection String url to override other settings (eg: mongodb://username:password@hostname:port/database):
? host: 127.0.0.1
? port: 27017
? user:
? password: [hidden]
? database: testapp
? Feature supported by MongoDB v3.1.0 and above: Yes
   create src\datasources\mongo-ds.datasource.json
   create src\datasources\mongo-ds.datasource.ts

npm WARN [email protected] No license field.

[email protected]
added 6 packages from 11 contributors and audited 4112 packages in 4.258s
found 0 vulnerabilities

   update src\datasources\index.ts
Datasource MongoDs was created in src\datasources/

C:\test>lb4 model
? Model class name: user
? Please select the model base class Entity (A persisted model with an ID)
? Allow additional (free-form) properties? No

Model User will be created in src/models/user.model.ts
Let's add a property to User

Enter an empty property name when done

? Enter the property name: id
? Property type: number
? Is id the ID property? Yes
? Is it required?: Yes
? Default value [leave blank for none]:

Let's add another property to User

Enter an empty property name when done

? Enter the property name: email
? Property type: string
? Is it required?: Yes
? Default value [leave blank for none]:

Let's add another property to User

Enter an empty property name when done

? Enter the property name: password
? Property type: string
? Is it required?: Yes
? Default value [leave blank for none]:

Let's add another property to User

Enter an empty property name when done

? Enter the property name:
   create src\models\user.model.ts
   update src\models\index.ts
Model User was created in src\models/

C:\test>lb4 model
? Model class name: userinfo
? Please select the model base class Entity (A persisted model with an ID)
? Allow additional (free-form) properties? No

Model Userinfo will be created in src/models/userinfo.model.ts

Let's add a property to Userinfo

Enter an empty property name when done

? Enter the property name: id
? Property type: number
? Is id the ID property? Yes
? Is it required?: Yes
? Default value [leave blank for none]:

Let's add another property to Userinfo

Enter an empty property name when done

? Enter the property name: firstname
? Property type: string
? Is it required?: No
? Default value [leave blank for none]:

Let's add another property to Userinfo

Enter an empty property name when done

? Enter the property name: lastname
? Property type: string
? Is it required?: No
? Default value [leave blank for none]:

Let's add another property to Userinfo

Enter an empty property name when done

? Enter the property name: bdate
? Property type: string
? Is it required?: No
? Default value [leave blank for none]:

Let's add another property to Userinfo

Enter an empty property name when done

? Enter the property name: activated
? Property type: boolean
? Is it required?: Yes
? Default value [leave blank for none]:

Let's add another property to Userinfo

Enter an empty property name when done

? Enter the property name:
   create src\models\userinfo.model.ts
   update src\models\index.ts

Model Userinfo was created in src\models/

C:\test>lb4 repository
? Please select the datasource MongoDsDatasource
? Select the model(s) you want to generate a repository User, Userinfo
? Please select the repository base class DefaultCrudRepository (Legacy juggler bridge)
   create src\repositories\user.repository.ts
   create src\repositories\userinfo.repository.ts
   update src\repositories\index.ts
   update src\repositories\index.ts

Repositories UserRepository, UserinfoRepository were created in src\repositories/

C:\test>lb4 controller
? Controller class name: user
Controller User will be created in src/controllers/user.controller.ts
? What kind of controller would you like to generate? REST Controller with CRUD functions
? What is the name of the model to use with this CRUD repository? User
? What is the name of your CRUD repository? UserRepository
? What is the name of ID property? id
? What is the type of your ID? number
? What is the base HTTP path name of the CRUD operations? /users
   create src\controllers\user.controller.ts
   update src\controllers\index.ts

Controller User was created in src\controllers/

C:\test>lb4 controller
? Controller class name: userinfo
Controller Userinfo will be created in src/controllers/userinfo.controller.ts
? What kind of controller would you like to generate? REST Controller with CRUD functions
? What is the name of the model to use with this CRUD repository? Userinfo
? What is the name of your CRUD repository? UserinfoRepository
? What is the name of ID property? id
? What is the type of your ID? number
? What is the base HTTP path name of the CRUD operations? /userinfos
   create src\controllers\userinfo.controller.ts
   update src\controllers\index.ts

Controller Userinfo was created in src\controllers/

C:\test>npm start
[email protected] prestart C:\test
npm run build

[email protected] build C:\test
lb-tsc

[email protected] start C:\test
node -r source-map-support/register .

Server is running at http://[::1]:3000
Try http://[::1]:3000/ping

For data :

 {
   "id":10,
   "email": "[email protected]",
   "password": "Abcd2018"
 }

schema/model of user:

 {
   "id": 0,
   "email": "string",
   "password": "string"
 }

I am getting following error:

 {
  "error": {
     "statusCode": 422,
     "name": "UnprocessableEntityError",
     "message": "The request body is invalid. See error object `details` property for more info.",
     "code": "VALIDATION_FAILED",
     "details": [
       {
         "path": "",
         "code": "not",
         "message": "should NOT be valid",
         "info": {}
       }
     ]
   }
 }
@rsa408 rsa408 added the question label Sep 3, 2019
@bajtos bajtos added the db:MongoDB Topics specific to MongoDB label Sep 3, 2019
@dhmlau
Copy link
Member

dhmlau commented Sep 3, 2019

Discussed it with @jannyHou, there might be a bug in generating the OpenAPI spec. When running the POST on debug, the output is:

loopback:rest:parser Validating request body - value {"value":{"id":12,"email":"[email protected]","password":"string"},"mediaType":"application/json","schema":{"$ref":"#/components/schemas/UserExcluding[id]"}} +9ms
  loopback:rest:validation Request body schema: "{ '$ref': '#/components/schemas/UserExcluding[id]' }" +0ms
  loopback:rest:validation Converted OpenAPI schema to JSON schema: { '$ref': '#/components/schemas/UserExcluding[id]' } +1ms
  loopback:rest:validation AJV options { allErrors: true, nullable: true, coerceTypes: false } +0ms
  loopback:rest:validation Invalid request body: { id: 12, email: '[email protected]', password: 'string' }. Errors: [ { keyword: 'not',
    dataPath: '',
    schemaPath: '#/components/schemas/UserExcluding[id]/not',
    params: {},
    message: 'should NOT be valid' } ] +28ms

If I remove the generated property, the request seem to be ok, and an id is added in the output. However, if I call GET, id is null.

@jannyHou
Copy link
Contributor

jannyHou commented Sep 3, 2019

? Enter the property name: id
? Property type: number
? Is id the ID property? Yes
? Is it required?: Yes
? Default value [leave blank for none]:

The id field is required but the generated schema has id excluded, that's why 422 error is thrown. Looking and fixing it.

@rsa408
Copy link
Author

rsa408 commented Sep 3, 2019

hi guys,
I send this error 3 days ago in the wrong place on this repo loopbackio/loopback4-example-shopping#256
Please check the @dougal83 's post there.

@rsa408
Copy link
Author

rsa408 commented Sep 3, 2019

In loopback3 Id was generated by loopback itself and there was no necessity to care about but in LB4 is much like relational database we can identify wich field to be id. maybe I am totally wrong.

@dhmlau
Copy link
Member

dhmlau commented Sep 3, 2019

Thanks @rsa408.

Cross posting comment from @dougal83 in loopbackio/loopback4-example-shopping#256 (comment):

The problem is an inconsistency between your model and the user controllers request body where one says include an id and the other says omit the value. Typically you would not supply an id, so I'd recommend that you set the user model id to be a string(for mongodb) that is not required and generated: true. This would (after running migrate) allow the database to provide a unique id.

For your project though to submit an id you need to alter the controller. Change schema: getModelSchemaRef(User, {exclude: ['id']}), to schema: getModelSchemaRef(User),

FYI - The id property that works for me is:

  @property({
    type: 'string',
    id: true,
  })
  id: string;

@rsa408
Copy link
Author

rsa408 commented Sep 5, 2019

I removed exclude from schema:

async create(
    @requestBody({
      content: {
        'application/json': {
          schema: getModelSchemaRef(Use_r, { exclude: ['id'] }_),
        },
      },
    })
    user: Omit<User, 'id'>,
  ): Promise<User> {
    return this.userRepository.create(user);
  }

then I add generated: true and removed required: true to the user model .

 @property({
    type: 'number',
    id: true,
    generated: true
  })
  id: number;

it is looking fine when I used POST method, for one record/document when in add several records it ( array of records )I get:

[{
		"email": "[email protected]",
		"password": "571087741"
	},
	{
		"email": "[email protected]",
		"password": "346470131"
	},
	{
		"email": "[email protected]",
		"password": "243339637"
	}]
{
  "error": {
    "statusCode": 500,
    "message": "Internal Server Error"
  }
}
Unhandled error in POST /users: 500 TypeError: model.toObject is not a function
    at UserRepository.toEntity (D:\apps\test\node_modules\@loopback\repository\src\repositories\legacy-juggler-bridge.ts:471:39)
    at UserRepository.create (D:\apps\test\node_modules\@loopback\repository\src\repositories\legacy-juggler-bridge.ts:338:17)

But regardless of the error message, it was POSted all records to MongoDB correctly data with autogenerated id.

@jannyHou
Copy link
Contributor

Fixed the controller generator's template in PR #3667.

@jomarocas
Copy link

update your loopback cli for working from now

sudo npm i -g @loopback/cli

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
db:MongoDB Topics specific to MongoDB
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants