Loopback - can't show error from controller - loopback

I'm new to loopback and I'm trying to return an error from a rest api controller created by cli with
"lb4 controller"
I don't know why Loopback always insert the data in db: what am I doing wrong???
Here is the code
#post('/tavolos', {
responses: {
'200': {
description: 'Tavolo model instance',
content: {'application/json': {schema: getModelSchemaRef(Tavolo)}},
},
},
})
async createTavolo(
#requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Tavolo, {
title: 'NewTavolo',
exclude: ['id'],
}),
},
},
})
tavolo: Omit<Tavolo, 'id'>,
): Promise<Tavolo> {
if (!Number.isInteger(Tavolo.max) || Tavolo.max > 10) {
throw new HttpErrors.BadRequest( `error text`, );
}
return this.tavoloRepository.create(tavolo);
}

I solved by myself: i just recreated the project (all models, controllers, etc...) and now it works... don't know where the error is.

Related

Where & Count cant be implemented together in Loopback 4

I am implementing an API that can take out all the data where user_id: user_id
but it is not working please help me to implement the same.
here is my code of Follow_api controller:
#get('/follow-masters/count/{id}')
#response(200, {
description: 'FollowMaster model count',
content: {'application/json': {schema: CountSchema}},
})
async findCount(
#param.path.string('user_id') user_id: string,
#param.where(FollowMaster) where?: Where<FollowMaster>,
): Promise<Count> {
return this.followMasterRepository.count();
}
Solved using this code:
#get('/follow-masters/count/{user_id}')
#response(200, {
description: 'FollowMaster model count',
content: {'application/json': {
schema: FollowMaster
}
},
})
async findCount(
#param.path.string('user_id') user_id: string,
#param.where(FollowMaster) where?: Where<FollowMaster>,
): Promise<NonVoid> {
return this.followMasterRepository.find({
where: {
user_id: user_id, ...where,
},
});
}

How to use Custom HTTP request and paginations, sort, search in Vue 2.x

I am an engineer who makes web systems in Tokyo.
I'm making a search system using Grid.js, but I faced a problem.
I don't know the solution because it's not in the documentation.
Since this system uses Vue 2.x, it uses axios.post with Custom HTTP Requset.
I was able to get the list, but I'm having trouble implementing sorting, pagination, and keyword search.
I want to send parameters by Post request.
Please tell me how to implement this.
The code is below
data() {
return {
columns: [
{name: 'user name', id: 'user_name'},
{name: 'email', id: 'email'},
],
page: {
enabled: true,
limit: 100,
server: {
body: (prev, page) => {
console.log(page) // OK, show page number 0,1,2...
return {
page: page
}
}
},
},
sort: {
},
search: {
server: {
// url: (prev, keyword) => `${prev}?q=${keyword}`
// what's this.
}
},
server: {
url: '/api/v2/users/list',
method: 'POST',
async data (opt) {
let response = await axios.post(opt.url)
return {
data: response.data.results.map(item => {
return {
username: item.username,
email: item.email,
}
}),
total: response.data.count,
}
}
},
};
OK.
Set POST payload this.
data() {
return {
columns: [
{name: 'user name', id: 'user_name'},
{name: 'email', id: 'email'},
],
page: {
enabled: true,
limit: 100,
server: {
body: (prev, page) => {
console.log(page) // OK, show page number 0,1,2...
return {
page: page
}
}
},
},
sort: {
},
search: {
server: {
// url: (prev, keyword) => `${prev}?q=${keyword}`
// what's this.
}
},
server: {
url: '/api/v2/users/list',
method: 'POST',
body: {},
async data (opt) {
let response = await axios.post(opt.url)
return {
data: response.data.results.map(item => {
return {
username: item.username,
email: item.email,
}
}),
total: response.data.count,
}
}
},
};

Loopback 4 - POST request dtasource template

I am having issue to declare POST operation in Loopback 4 datasource file.
My template is as follows:
{
"template": {
"method": "POST",
"url": "https://reqres.in/api/login"
},
"functions": {
"login": []
}
}
My service interface
login(email: string, password: string): Promise<any>;
My Controller
#post('/loginTest')
async testingLogin(
#requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(TestModel, {
title: 'Post',
}),
},
},
})
testModel: TestModel, )
: Promise<any> {
// TEST MODEL CONTAIN JSON OBJECT {email: "" , password: ""}
console.log("Test Model Representation: ", testModel)
try {
var response = await this.loginService.login(testModel.email, testModel.password);
} catch (error) {
console.log("error", error)
}
console.log("Fake POST response", response)
return response;
};
I am using this fake API : https://reqres.in/api/login
I am getting following error:
Test Model Representation: { email: 'string', password: 'string' }
error Error: {"error":"Missing email or username"}
at callback (D:\loginApp\node_modules\loopback-connector-rest\lib\rest-builder.js:541:21)
at D:\loginApp\node_modules\loopback-datasource-juggler\lib\observer.js:269:22
at doNotify (D:\loginApp\node_modules\loopback-datasource-juggler\lib\observer.js:157:49)
at RestConnector.ObserverMixin._notifyBaseObservers (D:\loginApp\node_modules\loopback-datasource-juggler\lib\observer.js:180:5) {
statusCode: 400,
message: '{"error":"Missing email or username"}'
}
Fake POST response undefined
It look like my email and password is not passed ? Thanks for any help.
The login function you defined in the datasource file should match with the service interface. That means it would be something like:
"functions": {
"login": ["email", "password"]
}

GraphQLError Schema validation while triggering a mutation

I am trying my hand at GraphQL and I seem to have run into a strange error.
Here is my mutation
const createNewTask = {
name: "AddATask",
description: "A mutation using which you can add a task to the todo list",
type: taskType,
args: {
taskName: {
type: new gql.GraphQLNonNull(gql.GraphQLString)
},
authorId: {
type: new gql.GraphQLNonNull(gql.GraphQLString)
}
},
async resolve(_, params) {
try {
const task = newTask(params.taskName);
return await task.save();
} catch (err) {
throw new Error(err);
}
}
};
Task type is as defined as follows
const taskType = new gql.GraphQLObjectType({
name: "task",
description: "GraphQL type for the Task object",
fields: () => {
return {
id: {
type: gql.GraphQLNonNull(gql.GraphQLID)
},
taskName: {
type: gql.GraphQLNonNull(gql.GraphQLString)
},
taskDone: {
type: gql.GraphQLNonNull(gql.GraphQLBoolean)
},
authorId: {
type: gql.GraphQLNonNull(gql.GraphQLString)
}
}
}
});
I am trying to add a task using the graphiql playground.
mutation {
addTask(taskName: "Get something", authorId: "5cb8c2371ada735a84ec8403") {
id
taskName
taskDone
authorId
}
}
When I make this query I get the following error
"ValidationError: authorId: Path `authorId` is required."
But when I remove the authorId field from the mutation code and send over a mutation without the authorId in it, I get this error
"Unknown argument \"authorId\" on field \"addTask\" of type \"Mutation\"."
So this proves that the authorId is available is in the request. I debugged the same on vscode and can see the value. I can't seem to figure out what is wrong.
I figured out what the error was. The erro was actually caused by my mongoose schema and not by graphql schema.
const taskSchema = new Schema(
{
taskName: {
type: String,
required: true
},
taskDone: {
type: Boolean,
required: true
},
authorId: {
type: mongoose.Types.ObjectId,
required: true
}
},
{
collection: "tasks"
}
);
But what is wierd is that the final error message has no indication that it was the mongoose schema validation failure. And the error states that it is a graphql error hence the confusion. Hope it helps someone.

receiving a 404 error when I make a post request to api server

I've created a custom endpoint for my api server which deletes a single hearing test:
Account.deleteSingleHearingTest = function (req, callback) {
// console.log('accounts.js: deleteSingleHearingTest: are we being reached????', req)
Account.findById(req.accessToken.userId)
.then(account => {
if (!account) {
throw new Error('Cannot find user');
}
console.log('account.js: deleteSingleHearingTest: req.body.hearingTestId N: ', req.body.hearingTestId);
return app.models.HearingTest.updateAll({ accountId: account.id, id: req.body.hearingTestId }, { isDeleted: new Date() });
})
.then(() => {
callback(null);
})
.catch(error => {
callback(error);
});
}
Account.remoteMethod(
'deleteSingleHearingTest', {
http: {
path: '/deleteSingleHearingTest',
verb: 'post'
},
accepts: [
{ arg: 'req', type: 'object', description: 'removes a single hearing test', http: { source: 'req' } }
],
description: 'this is the end point for a single delete',
returns: {}
}
);
I've also updated acls in account.json:
{
"accessType": "EXECUTE",
"principalType": "ROLE",
"principalId": "$authenticated",
"permission": "ALLOW",
"property": "deleteSingleHearingTest"
}
Using Postman, I made a POST request to the server address which looks something like :
https://xxx.xxxxxxxx.com/api/Accounts/deleteSingleHearingTest?access_token=XXXXXXXXXXXXXXXXXKyBdxkwxm5s8TSceMgclvXjjrTnyn3UJWIa
The response I get back on Postman is a 404 with the attached message
"Shared class \"Account\" has no method handling POST /deleteSingleHearingTest?access_token=XXXXXXXXXXXXXXXXXXqAoKyBdxkwxm5s8TSceMgclvXjjrTnyn3UJWIa",
The strange thing is, this method was working two weeks ago when I first created, the only difference was that I was running the server locally.
I needed to restart the server so the new methods could be pulled in. For the 1 person who actually reads this. To restart the server the command is pm2 start all