I have a list object like:
"my_list":
[
{
"id": 1,
"name": A
},
{
"id": 2,
"name": B
},
]
I want to convert to key - value like:
my_list = {
1: 'A',
2: 'B'
}
How can I do that? Does anyone have solution?
Please help, thanks!
Cast it to Laravel collection and use mapWithKeys()
$keyed = collect($my_list)->mapWithKeys(function ($item) {
return [$item['id'] => $item['name']];
});
If you need to convert it to object then:
$keyed = (object)$keyed->toArray();
You can use array helper methods combines with array_combine():
(object)array_combine(Arr::pluck($my_list, 'id'), Arr::pluck($my_list, 'name'));
I would like to add a condition based on the tasks relationship count,
Here is the code:
return TeamleaderDeal
::withCount('tasks')
->get();
The result is:
[
{
"id": 4,
(...)
"dealPhase": "Refused",
"tasksCount": 5,
(...)
},
{
"id": 5,
(...)
"tasksCount": 0,
"companyLanguage": "nl",
(...)
},
{
"id": 16,
(...)
"dealPhase": "New",
"tasksCount": 17,
(...)
},
{
(...)
How to only return results where tasksCount equal to 5?
You may use has method like this:
// Retrieve all team-leader deals that have 5 tasks...
return TeamleaderDeal
::has('tasks', '=', 5)
->get();
Check Laravel docs for more info.
return Cache::remember('districts.all',60*60, function (){
return District::all();
});
cache collection is
[
{
"id": 1,
"title": "Dhaka"
},
{
"id": 2,
"title": "Rajshahi"
},
{
"id": 3,
"title": "Barishal"
}
]
now how to add new in districts.all cache
"id":4 ,
"title":"New District"
and also how to update this cache
"id":3,
"title":"Khulna"
Laravel doesn't have a special function to update cache directly, but you still can clear districts.all and redefine it again with the new value:
Cache::forget('districts.all');
$district = new District();
$district->id = 4;
$district->name = "New District";
Cache::remember('districts.all', 60*60, function () use ($district) {
return District::all()->push($district);
});
Pretty straightforward (I hope). I'd like to be able to use the API endpoint and have it only return specified fields. I.E. something like this
http://localhost:1337/api/reference?select=["name"]
Would ideally return something of the form
[{"name": "Ref1"}]
Unfortunately that is not the case, and in actuality it returns the following.
[
{
"contributors": [
{
"username": "aduensing",
"email": "standin#gmail.com",
"lang": "en_US",
"template": "default",
"id_ref": "1",
"provider": "local",
"id": 1,
"createdAt": "2016-07-28T19:39:09.349Z",
"updatedAt": "2016-07-28T19:39:09.360Z"
}
],
"createdBy": {
"username": "aduensing",
"email": "standin#gmail.com",
"lang": "en_US",
"template": "default",
"id_ref": "1",
"provider": "local",
"id": 1,
"createdAt": "2016-07-28T19:39:09.349Z",
"updatedAt": "2016-07-28T19:39:09.360Z"
},
"updatedBy": {
"username": "aduensing",
"email": "standin#gmail.com",
"lang": "en_US",
"template": "default",
"id_ref": "1",
"provider": "local",
"id": 1,
"createdAt": "2016-07-28T19:39:09.349Z",
"updatedAt": "2016-07-28T19:39:09.360Z"
},
"question": {
"createdBy": 1,
"createdAt": "2016-07-28T19:41:33.152Z",
"template": "default",
"lang": "en_US",
"name": "My Question",
"content": "Cool stuff, huh?",
"updatedBy": 1,
"updatedAt": "2016-07-28T19:45:02.893Z",
"id": "579a5ff83af4445c179bd8a9"
},
"createdAt": "2016-07-28T19:44:31.516Z",
"template": "default",
"lang": "en_US",
"name": "Ref1",
"link": "Google",
"priority": 1,
"updatedAt": "2016-07-28T19:45:02.952Z",
"id": "579a60ab5c8592c01f946cb5"
}
]
This immediately becomes problematic in any real world context if I decide to load 10, 20, 30, or more records at once, I and end up loading 50 times the data I needed. More bandwidth is used up, slower load times, etc.
How I solved this:
Create custom controller action (for example, 'findPaths')
in contributor/controllers/contributor.js
module.exports = {
findPaths: async ctx => {
const result = await strapi
.query('contributor')
.model.fetchAll({ columns: ['slug'] }) // here we wait for one column only
ctx.send(result);
}
}
Add custom route (for example 'paths')
in contributor/config/routes.json
{
"method": "GET",
"path": "/contributors/paths",
"handler": "contributor.findPaths",
"config": {
"policies": []
}
},
Add permission in admin panel for Contributor entity, path action
That's it. Now it shows only slug field from all contributor's records.
http://your-host:1337/contributors/paths
Here is how you can return specific fields and also exclude the relations to optimize the response.
async list (ctx) {
const result = await strapi.query('article').model.query(qb => {
qb.select('id', 'title', 'link', 'content');
}).fetchAll({
withRelated: []
}).catch(e => {
console.error(e)
});
if(result) {
ctx.send(result);
} else {
ctx.send({"statusCode": 404, "error": "Not Found", "message": "Not Found"});
}
}
I know this is old thread but I just run into exactly same problem and I could not find any solution. Nothing in the docs or anywhere else.
After a few minutes of console logging and playing with service I was able to filter my fields using following piece of code:
const q = Post
.find()
.sort(filters.sort)
.skip(filters.start)
.limit(filters.limit)
.populate(populate);
return filterFields(q, ['title', 'content']);
where filterFields is following function:
function filterFields(q, fields) {
q._fields = fields;
return q;
}
It is kinda dirty solution and I haven't figured out how to apply this to included relation entites yet but I hope it could help somebody looking for solution of this problem.
I'm not sure why strapi does not support this since it is clearly capable of filtering the fields when they are explicitly set. it would be nice to use it like this:
return Post
.find()
.fields(['title', 'content'])
.sort(filters.sort)
.skip(filters.start)
.limit(filters.limit)
.populate(populate);
It would be better to have the query select the fields rather than relying on node to remove content. However, I have found this to be useful in some situations and thought I would share. The strapi sanitizeEntity function can include extra options, one of which allows you only include fields you need. Similar to what manually deleting the fields but a more reusable function to do so.
const { sanitizeEntity } = require('strapi-utils');
let entities = await strapi.query('posts').find({ parent: parent.id })
return entities.map(entity => {
return sanitizeEntity(entity, {
model: strapi.models['posts'],
includeFields: ['id', 'name', 'title', 'type', 'parent', 'userType']
});
});
This feature is not implemented in Strapi yet. To compensate, the best option for you is probably to use GraphQL (http://strapi.io/documentation/graphql).
Feel free to create an issue or to submit a pull request: https://github.com/wistityhq/strapi
You can use the select function if you are using MongoDB Database:
await strapi.query('game-category').model.find().select(["Code"])
As you can see, I have a model called game-category and I just need the "Code" field so I used the Select function.
In the current strapi version (3.x, not sure about previous ones) this can be achieved using the select method in custom queries, regardless of which ORM is being used.
SQL example:
const restaurant = await strapi
.query('restaurant')
.model.query((qb) => {
qb.where('id', 1);
qb.select('name');
})
.fetch();
not very beautiful,but you can delete it before return.
ref here:
https://strapi.io/documentation/developer-docs/latest/guides/custom-data-response.html#apply-our-changes
const { sanitizeEntity } = require('strapi-utils');
module.exports = {
async find(ctx) {
let entities;
if (ctx.query._q) {
entities = await strapi.services.restaurant.search(ctx.query);
} else {
entities = await strapi.services.restaurant.find(ctx.query);
}
return entities.map(entity => {
const restaurant = sanitizeEntity(entity, {
model: strapi.models.restaurant,
});
if (restaurant.chef && restaurant.chef.email) {
**delete restaurant.chef.email;**
}
return restaurant;
});
},
};
yeah,I remember another way.
you can use the attribute in xx.settings.json file.
ref:
model-options
{
"options": {
"timestamps": true,
"privateAttributes": ["id", "created_at"], <-this is fields you dont want to return
"populateCreatorFields": true <- this is the system fields,set false to not return
}
}
You can override the default strapi entity response of:-
entity = await strapi.services.weeklyplans.create(add_plan);
return sanitizeEntity(entity, { model: strapi.models.weeklyplans });
By using:-
ctx.response.body = {
status: "your API status",
message: "Your own message"
}
Using ctx object, we can choose the fields we wanted to display as object.
And no need to return anything. Place the ctx.response.body where the response has to be sent when the condition fulfilled.
It is now 2023, and for a little while it has been possible to do this using the fields parameter:
http://localhost:1337/api/reference?fields[0]=name&fields[1]=something
I've created this code from laravel:
public function findConfig($id)
{
$config = DB::table('configuration')
->join('model', 'model.configuration_id','=', 'configuration.id')
->select('configuration.id','configuration.description', 'model.name','configuration.price')
->where('configuration.id','=', $id)
->get();
$encode = json_encode($config, JSON_UNESCAPED_SLASHES);
$response = Response::make($encode, 200);
$response->header('Content-Type', 'application/json');
return $response;
}
then the return is somehow like this
[{
"id": "1",
"description": "{\"item\":[{'colours\":[\"red\",\"blue\",\"green\"]},{\"motors\":[ {\"name\":\"450W/48V\",\"price\":\"2,000\"},{\"name\":\"550W/48V\", \"price\":\"3,000\" }] } ]}",
"name": "k5-A",
"price": "300000"
},
{
"id": "1",
"description": "{\"item\":[{'colours\":[\"red\",\"blue\",\"green\"]},{\"motors\":[ {\"name\":\"450W/48V\",\"price\":\"2,000\"},{\"name\":\"550W/48V\", \"price\":\"3,000\" }] } ]}",
"name": "r-A",
"price": "300000"
}
]
How can I remove the slashes and instead of string as return type, it should be in JSON?
As lukasgeiter said, generally it isn't a good idea to store json in a db. It may get difficult to filter by that field.
If you decide to do so, and need to get the decoded data, you can use an accessor in the model. I don't know if it is the best practice. If the description is saved in the db as a json you can do this:
For the "configuration" table you may have a "Configuration" model (The official Laravel website recommends to name the table in plural, and the model in it's singular, like: table -> configurations and the model configuration). In that file you can add this:
public function getDescriptionAttribute($value)
{
return json_decode($value, true);
}
Now, the description field is returned as an array.
You can see more about accessors and mutators here: http://laravel.com/docs/4.2/eloquent#accessors-and-mutators