LoopBack 4 REST API example for getting record with Mysql - mysql

i'm learning loopback 4, i have created model, repository and datasource, it also connected
to mysql and i can retrieve results from http://127.0.0.1:3000/myapi/{id}
in my default example getting by id is :
#get('/citySchedule/{id}', {
responses: {
'200': {
description: 'Schedule model instance',
content: {'application/json': {schema: {'x-ts-type': Schedule}}},
},
},
})
async findById(#param.path.number('id') id: number): Promise<Schedule> {
return await this.ScheduleRepository.findById(id);
}
However, i didnt found any tutorial for getting data with more parameters.
let say mysql table of schedule has contain column id, city_name, city_code, date, task, item.
for example, i want to get "SELECT task, item FROM schedule WHERE city_code=123 AND date=2019-05-01"
my question, how to write code to get those data at loopback controller ?
any example code...
my expectations, i can query from my api :
http://127.0.0.1:3000/myapi/{city_code}/{date}/ to get data results or
http://127.0.0.1:3000/myapi/{city_name}/{date}/

If you have generated your controller using loopback cli, you must have got another method in controller class like this
#get('/citySchedule', {
responses: {
'200': {
description: 'Array of Schedule model instances',
content: {
'application/json': {
schema: {type: 'array', items: {'x-ts-type': Schedule}},
},
},
},
},
})
async find(
#param.query.object('filter', getFilterSchemaFor(Schedule)) filter?: Filter,
): Promise<Schedule[]> {
return await this.ScheduleRepository.find(filter);
}
You can use this API to fetch more filtered data.
Considering your example
SELECT task, item FROM schedule WHERE city_code=123 AND
date=2019-05-01
for this query, you need to hit the API like this.
GET /citySchedule?filter=%7B%22where%22%3A%7B%22city_code%22%3A123%2C%22date%22%3A%222019-05-01%22%7D%2C%22fields%22%3A%7B%22task%22%3Atrue%2C%22item%22%3Atrue%7D%7D
Here, the filter query parameter value is actually url encoded string for the below json string
{
"where":{
"city_code":123,
"date":"2019-05-01"
},
"fields":{
"task":true,
"item":true
}
}

Related

GraphiQL Returning null Values When Fetching All Records [duplicate]

This question already has answers here:
Why does a GraphQL query return null?
(6 answers)
Closed 3 years ago.
I am trying to build a simple GraphQL schema. I have an json-server endpoint running on localhost which returns some simple json data.
I can return a user when supplying an id. The query to do this in the schema looks like this:
staff: {
type: StaffType,
args: { id: { type: GraphQLInt }},
resolve(parentValue, { id }) {
return axios.get(`http://localhost:3000/staff/${id}`)
.then(resp => resp.data);
}
}
The GraphQL query looks like this:
{
staff(id: 1){
id
Name
}
}
and it returns this in the GraphiQL client:
{
"data": {
"staff": {
"id": 1,
"Name": "John Doe"
}
}
}
My problem starts when I try to return all users. I created another query to try to just fetch everything from http://localhost:3000/staff with no args passed in. If I go directly to this url in the browser it returns all users as expected. If I try it via GraphiQL, however, it seems to return an object, but all the fields are null. There is no error given either in GraphiQL or on the console. Code examples below:
The query in the schema
allStaff: {
type: StaffType,
resolve(parentValue, args) {
return axios.get(`http://localhost:3000/staff/`)
.then(resp => resp.data);
}
}
The GraphiQL query
{
allStaff {
id
Name
}
}
The result I'm getting
{
"data": {
"allStaff": {
"id": null,
"Name": null,
}
}
}
if I console log resp.data there is data being returned and, as I say, the endpoint returns data when I access it directly via the browser exactly as expected.
Have I missed something?
Thanks
The JSON data may be an array of user objects, but GraphQL is still expecting just the one. That's because in your schema, you've defined the return type for allStaff as StaffType. You need to wrap it with the List wrapper, like this:
type: new GraphQLList(StaffType),

How to update a response through LimeSurvey's Remote Control (JSON)

I'm trying to modify a single response through Remote Control using request promise native with a Node Server, so far all API calls have been successful, unfortunately "update_response" has not.
this is what I've got:
var options = {
uri: "http://localhost/admin/remotecontrol",
method: "POST",
body: {
method:'update_response',
params:[sessionkey,surveyid,{ id: 5, token: "aValidToken", aValidColumnName: "a perfectly normal string" }],
id:1
},
json: true
};
request(options).then((body) => {
console.log(body.result);
}).catch((err) => {
res.send(err);
});
The LimeSurvey API docummentation is not quite clear as to what structure the third parameter should have (https://api.limesurvey.org/classes/remotecontrol_handle.html#method_update_response), funnily enough if I only pass { id: 5, token: "aValidToken" } it does work (outputs "true"), with a key value pair though I'm getting:
Error: Invalid Column names supplied: aValidColumnName
Has anyone had success with this?
The column names are the question or sub-question IDs - https://manual.limesurvey.org/SGQA_identifier/en
I would think that the third parameter is an array of question/sub-question IDs and answers.
{'123':'A1', '124':'A3', '128':'Some text input...'}

EmberJS 2.7 How to restructure/reformat/customize data returned from the store

I have what I think is a very simple issue, but I just don't get how to do this data manipulation. This sadly didn't help, even though it's the same pain I am feeling with Ember.
Here is a route:
route/dashboard.js:
import Ember from 'ember';
export default Ember.Route.extend({
// this is for testing, normally we get the data from the store
model: function() {
return this.get('modelTestData');
},
modelTestData: [{
name: 'gear',
colorByPoint: true,
data: [
{y: 10, name: 'Test1'},
{y: 12, name: 'Test2'},
{y: 40, name: 'Test3'}
]
}],
});
The structure of the 'modelTestData' object has to be exactly like that as it is passed into a child component that needs it structured that way.
I can easily get my data from the API and put it into the model:
model: function() {
return this.store.get('category');
},
But then I need to restructure it...but how?
I have to somehow iterate over the categories collection and extract parts of data from each record to replace the 'data' part of the modelTestData object.
So I have 3 issues I am completely stumped on:
How to 'get at' the attributes I need from the model?
How to structure them as an array of objects with 'y' and 'name'?
How to assign that structure to the 'data' property of modelTestData instead of it being hardcoded?
Categories is a JSONAPI object like this:
{
"data":[
{
"id":"1",
"type":"categories",
"attributes":{
"name":"Carrying system",
"total-grams":"0.0"
}
},
{
"id":"2",
"type":"categories",
"attributes":{
"name":"Shelter system",
"total-grams":"0.0"
}
}
]
}
I need to map the grams value to 'y' and the name to 'name' in modelTestData.
Note that the category data is used in other routes for other purposes exactly as returned by the API. So I don't want to change the model structure itself, or what the API returns...that will break other parts of the app that do use 'category' in its original structure.
This is a specific use case that this route needs to massage the data to pass to the child component as per the structure of modelTestData.
I also wonder whether this data manipulation task belongs in a route?
Should I somehow do this in the serliazer adapter, creating a new structure as say 'categoryWeights' so I can then do:
model: function() {
return this.store.get('categoryWeights');
},
EDIT
I have managed to do this in the route, but it just gives me an array of objects. I need a single object containing 2 properties and an embedded array of objects.
model() {
return this.store.findAll('category')
.then(categories => categories.map(category => {
let data = {
y: category.get('totalGrams'),
name: category.get('name')
};
return data;
}))
},
This should probably go into a computed property:
dataForSubModel: Ember.computed('model.#each.totalGrams', 'model.#each.name', {
get() {
return [{name: 'gear', colorByPoint: true, this.get('model').map(m => ({y:m.get('totalGrams'), name:m.get('name')}))}
}
}),
The serializer is the wrong place, because its not that you need to convert it between the server and your app, but between your app and a strange component.
Actually the best thing would be to refactor the component.
Ok I got this to work in the route.
model() {
return this.store.findAll('category')
.then( function(categories) {
let data = [];
data = categories.map(category => {
return {
y: category.get('totalGrams'),
name: category.get('name')
}
});
return [{name: 'gear', colorByPoint: true, data}];
})
},
I still have the feeling this should be done in the adapter or serializer. Would be happy to see answers that show how to do that.

Emit couchbase data

I would like to emit couchbase data in the following format :
rows: [
{
id: "UniqueID",
key: "UniqueKey",
doc: {
meta: {
id: "UniqueID"
},
json: {
//ACTUAL DOCUMENT HERE
}
}
}
,
.... Second document and so on
When I try to create a view :
function (doc, meta) {
emit(meta.id, doc);
}
It emits the data in the following fashion :
total_rows: 55, -- DO NOT NEED THIS
rows: [
{
id: "UniqueID",
key: "UniqueKey",
value: {
//ACTUAL DOCUMENT HERE
}
},
.... Second document and so on
How do I modify the view to output the exact same schema as mentioned above ?
You don't. View response follows a defined format that tools like the SDKs rely on for parsing.
Also it is generally not a good idea to emit the whole document: since the value of the view get stored in the secondary index, you are basically duplicating all your data in the key/value store and the view index...
View responses always include the document ID for a particular row, so you can always get the document by performing a key/value GET. The SDKs can also abstract that away in their API (eg. in Java there's a document() method on each row object).

Odata: The query parameter '$count' is not supported

Server: Odata controllers generated with standard VS 2015 generator.
// GET: odata/MyEntities
[EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
public IQueryable<Models.Odata. MyEntity> GetMyEntities()
{
return db.MyEntities;
}
Client: KendoUI
var ds = new kendo.data.HierarchicalDataSource({
type: "odata-v4",
transport: {
read: {
url: "odata/EndPoints",
dataType: "json"
}
},
schema: {
model: {
id: "Id",
}
}
});
Request:
http://localhost:44444/odata/MyEntities?$format=json - returns whats expected,
but
http://localhost:44444/odata/MyEntities?$format=json&$count=true - produces error:
{
"odata.error":{
"code":"","message":{
"lang":"en-US","value":"The query parameter '$count' is not supported."
}
}
}
I used standard settings in AppStart. What is it?
Try using Microsoft.AspNet.OData namespace instead of System.Web.Http.OData in your controller.
OData version 3 has a query option named $inlinecount, not $count. It appears you are confusing the query option with both the /$count path segment, and the $count query option from version 4.
Request the total count of entities in a collection, along with the entities themselves:
GET http://localhost:44444/odata/MyEntities?$format=json&$inlinecount=allpages
Request only the count of an entity collection:
GET http://localhost:44444/odata/MyEntities/$count?$format=json
See OData Version 3.0 Core Protocol, sections 10.2.3.6 and 10.2.5.