Vue: How to bind checked value from array of objects - javascript

For the last 10 hours straight i'm struggling with a seemingly simple issue, i hope someone can assist me.
Situation:
data: {
user: {
email: 'test#test.com',
has_items: [
{ "id": 19, "userId": 63, "projectId": 1, "project": { "id": 1, "titel": "Project1" } },
{ "id": 20, "userId": 63, "projectId": 2, "project": { "id": 2, "titel": "Project2" } }
]
},
items: [
{ "label": "Project1", "titel": "Project1", "projectId": 1 },
{ "label": "Project2", "titel": "Project2", "projectId": 2 },
{ "label": "Project3", "titel": "Project3", "projectId": 3 }
]
}
However, i can't seem to bind the has_items projectId to the checkbox checked state. I'm pretty confident it's one of those cases where messing around made things worse, and a simple solution is overlooked.
I've added an example fiddle: http://jsfiddle.net/ebzgr4c3/31/
Hope someone can point out the error i made, and make this work :)
Thanks!

Because the elements in user.has_items have some extra formatting compared to the elements in items, I don't think v-model is really an option here. You'll need space to make some sort of translation from item to has_item happen between the time the checkbox is checked and the time the project is pushed onto the user's array.
You can make that space by trading v-model for a more manual option: events. In my example here, I used the change event to trigger a method that adds or removes the project, based on whether the checkbox is checked or unchecked.
I set the checkbox's initial value with another method. This method checks whether the checkbox's associated project is in the user's array of items.
var demo = new Vue({
el: '#app',
data: {
user: {
email: 'test#test.com',
has_items: [
{ "id": 19, "userId": 63, "projectId": 1, "project": { "id": 1, "titel": "Project1" } },
{ "id": 20, "userId": 63, "projectId": 2, "project": { "id": 2, "titel": "Project2" } }
]
},
items: [
{ "label": "Project1", "titel": "Project1", "projectId": 1 },
{ "label": "Project2", "titel": "Project2", "projectId": 2 },
{ "label": "Project3", "titel": "Project3", "projectId": 3 }
]
},
methods: {
userHasItem(project) {
return this.user.has_items.find(e => e.projectId == project.projectId) != undefined;
},
updateHasItems(checked, project) {
if (checked) {
// Add item to user.has_items
// [Translation between item and has_item goes here]
this.user.has_items.push(project);
}
else {
// Remove item from user.has_items based on ID
this.user.has_items.splice(this.user.has_items.findIndex(e => e.projectId == project.projectId), 1);
}
},
},
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
<div v-for="project in items" :key="project.projectId">
<label>{{project.titel}}</label>
<input type="checkbox" :checked="userHasItem(project)" :value="project" #change="updateHasItems($event.target.checked, project)"/>
</div>
<p>User's items</p>
{{user.has_items}}
</div>

Related

Get minimum column value from related entity

Please, help me. I cant find information about how do this.
I have got this code. It load all products with all relations. One of relations is product item. In product item entity I have got price column.
How I can get minimal product item price without get in my response array of product items?
const { skip, take } = pagination;
const query = this.createQueryBuilder('product');
query.where('product.shop = :id AND product.blocked = FALSE', {
id: shop.id,
});
if (skip) {
query.offset(Number(skip));
}
if (take) {
query.limit(Number(take));
}
query.leftJoin('product.info', 'info');
query.leftJoin('product.avatar', 'avatar');
// load product items
query.leftJoin('product.productItem', 'item');
query.select([
'product.id',
'product.path',
'info.name',
'info.description',
'info.info',
'info.lang',
'avatar.path',
'avatar.type',
'item.price'
]);
const [list, amount] = await query.getManyAndCount();
Now i have got:
{
"list": [
{
"id": 3,
"path": "admin-product-2",
"order": 1,
"shop": {
"id": 1
},
"info": [
{
"name": "Admin Name ;)",
"description": "Shorty",
"info": "",
"lang": "RU"
}
],
"avatar": null,
"productItem": [
{
"price": 1000
},
{
"price": 500
},
{
"price": 300
},
{
"price": 2000
},
{
"price": 3000
}
]
}
]
}
........
But I need:
{
"list": [
{
"id": 3,
"path": "admin-product-2",
"order": 1,
"shop": {
"id": 1
},
"info": [
{
"name": "Admin Name ;)",
"description": "Shorty",
"info": "",
"lang": "RU"
}
],
"avatar": null,
"minProductItemPrice": 300
}
]
}
Pls help me
You can find the answer for this on Stackoverflow already.
Here is a similar question Typeorm select max with specific column
Basically, getManyAndCount() method that you are using is useful when fetching entities. In your case, you are trying to obtain an aggregate value encompassing multiple entities.
You need to make separate selection, like so
query.select("MIN(item.price)", "min");
and then get the result with
return query.getRawOne();

Postman - How to count occurrences of a specific object in a JSON response

I am new to JSON and Postman. I believe I'm trying to do something very simple.
I have created a GET request which will get a JSON response like the one below.
In the example below I want to get the count of All "IsArchived" attributes in the response;
The number of those attributes will vary from response to response.
How can I do it? Thanks in advance
{
"Id": 1328,
"Name": "AAA Test",
"Owner": {
"Id": 208,
"Name": "The Boss"
},
"FieldGroups": [
{
"Id": "c81376f0-6ac3-4028-8d61-76a0f815dbf8",
"Name": "General",
"FieldDefinitions": [
{
"Id": 1,
"DisplayName": "Product Name",
"IsArchived": false
},
{
"Id": 2,
"DisplayName": "Short Description",
"IsArchived": false
},
{
"Id": 33,
"DisplayName": "Long Description",
"IsArchived": false
},
]
},
{
"Id": "5ed8746b-0fa8-4022-8216-ad3af17db91f",
"Name": "Somethingelse",
"FieldDefinitions": [
{
"Id": 123,
"DisplayName": "Attribution",
"IsArchived": false
},
{
"Id": 1584,
"DisplayName": "FC1",
"IsArchived": false
},
{
"Id": 623,
"DisplayName": "Sizes",
"IsArchived": false,
"Owner": {
"Id": 208,
"Name": "The Boss"
},
"Unit": "",
"Options": [
{
"Id": 1,
"Value": "XS"
},
{
"Id": 2,
"Value": "S"
},
{
"Id": 3,
"Value": "M"
}
]
}
]
}
],
"IsArchived": false
"Version": 1
}
It is a rather specific solution but I hope it helps. The description is added as comments:
// Convert the response body to a JSON object
var jsonData = pm.response.json()
// Create a count variable which will be increased by 1 everytime IsArchived occurs
var count = 0;
function countIsArchived() {
// Loop through the FieldGroupsArray
_.each(jsonData.FieldGroups, (fieldGroupsArray) => {
// Loop through the FieldDefinitionsArray
_.each(fieldGroupsArray.FieldDefinitions, (fieldDefinitionsArray) => {
// Check if IsArchived exists
if(fieldDefinitionsArray.IsArchived) {
// Increase count by 1
count++;
}
});
});
// IF you want it:
// Check if IsArchived exists on the top level of the JSON response and increase count
if(jsonData.IsArchived) {
count++;
}
// IF you want it:
// Create a Postman environment variable and assign the value of count to it
pm.environment.set("count", count);
}
Additional info:
The , after the following object is not needed. It invalidates the JSON:
{
"Id": 33,
"DisplayName": "Long Description",
"IsArchived": false
}, <--

Analysis Paralysis in looping over JSON data to populate select box with optgroup sections

I have Analysis Paralysis and need some input. I can modify the SQL query, the JavaScript, AND/or the CFML controller (all code has been posted below).
All I'm looking to do is to populate a select box with options and optgroups. The optgroup is what is tripping me up here.
The sql is pretty basic and looks like this:
SELECT
g.groupID,
g.groupLabel,
u.unitLabel,
u.unitID
FROM
group g
LEFT JOIN unit u ON g.groupID = u.groupID
And the CFML loop(s) is as follows (this is also where I believe the adjustment should be made with some logic such as if thisGroupLabel matches the preGroupLabel, stay within loop and keep adding unitLabel and unitIDs) but is there a more efficient way?:
local.data.unitLabels = [];
for(local.row in local.__unitLabels){
local.unit = {};
local.unit.groupLabel = local.row.groupLabel;
local.unit.unitLabel = local.row.unitLabel;
local.unit.unitID = local.row.unitID;
// loop over the array so that we can identify which one needs to be preselected
for(local.dataValue in local.data.unitDetails){
if (local.unit.unitID eq local.dataValue.unitID) {
local.unit.selected = 'selected';
} else {
local.unit.selected = '';
}
}
arrayAppend(local.data.unitLabels, local.unit);
}
The JSON data looks like this but I have access to the query so I can reformat it if needed:
{
"data": {
"selectDataOptions": [{
"groupLabel": "COMPLETION",
"selected": "",
"unitID": 1,
"unitLabel": "Completion"
}, {
"groupLabel": "DISTANCE",
"selected": "",
"unitID": 2,
"unitLabel": "Meters"
}, {
"groupLabel": "DISTANCE",
"selected": "",
"unitID": 3,
"unitLabel": "Miles"
}, {
"groupLabel": "DISTANCE",
"selected": "",
"unitID": 4,
"unitLabel": "Yards"
}, {
"groupLabel": "TIME",
"selected": "",
"unitID": 5,
"unitLabel": "Hours"
}, {
"groupLabel": "TIME",
"selected": "",
"unitID": 5,
"unitLabel": "minutes"
}, {
"groupLabel": "TIME",
"selected": "",
"unitID": 5,
"unitLabel": "Seconds"
}]
}
}
As it stands, my select box looks like this (roughly):
<select>
<optgroup>COMPLETION</optgroup>
<option>Complettion</option>
<optgroup>DISTANCE</OPTGROUP>
<option>Meters</option>
<optgroup>DISTANCE</optgroup>
<option>Miles</option>
<optgtroup>DISTANCE</optgroup>
<option>Yards</option>
<optgtroup>TIME</optgroup>
<option>Hours</option>
<optgtroup>TIME</optgroup>
<option>Minutes</option>
</select>
Notice that the optgroup Distance and TIME are repeated. The desired output would look like this:
<select>
<optgroup>COMPLETION</optgroup>
<option>Complettion</option>
<optgroup>DISTANCE</OPTGROUP>
<option>Meters</option>
<option>Miles</option>
<option>Yards</option>
<optgroup>TIME</optgroup>
<option>Hours</option>
<option>Mintues</option>
</select>
Is the issue how to construct a JSON string that Select2 can understand? I'd suggest creating a nested array of children for each GroupLabel, as described in the documentation under Grouped Data.
CF11+ and Lucee 4.5+ support cfloop "group", which would make things a lot easier. Just cfloop through the query and group by "groupLabel". (NB: Don't forget to modify the SQL query and ORDER BY g.groupLabel so the grouping works as expected.)
TryCF.com Example
Code:
data= [];
cfloop(query="qDemo", group="groupLabel") {
children = [];
cfloop() {
arrayAppend(children, {"id": qDemo.unitID, "text": qDemo.unitLabel});
}
arrayAppend(data, {"text" : qDemo.GroupLabel, "children" : children });
}
writeDump(serializeJSON(data));
Result:
[
{
"text": "COMPLETION",
"children": [
{
"text": "Completion",
"id": 1
}
]
},
{
"text": "DISTANCE",
"children": [
{
"text": "Meters",
"id": 2
},
{
"text": "Miles",
"id": 3
},
{
"text": "Yards",
"id": 4
}
]
},
{
"text": "TIME",
"children": [
{
"text": "Hours",
"id": 5
},
{
"text": "minutes",
"id": 5
},
{
"text": "Seconds",
"id": 5
}
]
}
]

React / Redux - how to render/update deeply nested sate

I'll get from the API a deeply nested state - e.g.:
[{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": []
}]
}]
}]
}]
(Please ignore duplicate ids etc)
Now here are the requirements:
I need to properly render this
e.g.
<div>
text
<div>
text
</div>
</div>
I need to be able to update the nested state within redux store
This list can be huge - like at least 3k items (which theoretically works fine)
What I tried:
Having everything unnested:
Rendering is very complicated (with parentId)
Maintaining the structure is difficult (need to flatten and unflatten it) -> this costs a lot of performance
Having everything nested:
Updating the store is impossible without "cheating" in react -> manipulating the state directly
What can be a solution to this? What should be the architecture
Something like immutability-helper will probably be of use to you here.
const state = [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": []
}]
}]
}]
}];
const newState = update(state, {
0: {
children: {
0: {
children {
0 : {
children: {
0: {
"id": { $set: 2}
}
}
}
}
}
}
};
return newState;
[{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 1,
"text": "test",
"children": [{
"id": 2,
"text": "test",
"children": []
}]
}]
}]
}];
The 0s here could be replaced with some indexes in your payload; I just used 0 here as the example arrays all have only 1 element in them. This is quite deeply nested though so as the comments pointed out, any flattening you can do will make the updates easier.

Searching and editing nested JSON elements

Basically I want to be able, in Javascript (JQuery optionally), to search into a JSON with nested elements for a particular element and edit it.
Ex. search for "components" with id 110 and change the name to "video card".
Notice the following JSON is just an example. I am wondering if javascript libraries or good tricks exist to do such a thing, I don't think traversing the whole json or writing my own methods is the best solution.
{
"computers": [
{
"id": 10,
"components": [
{
"id": 56,
"name": "processor"
},
{
"id": 24,
"name": "ram"
}
]
},
{
"id": 11,
"components": [
{
"id": 110,
"name": "graphic card"
},
{
"id": 322,
"name": "motherboard"
}
]
}
]
}
You could try linq.js.
You can use this javascript lib, DefiantJS (http://defiantjs.com), with which you can filter matches using XPath on JSON structures. To put it in JS code:
var data = {
"computers": [
{
"id": 10,
"components": [
{ "id": 56, "name": "processor" },
{ "id": 24, "name": "ram" }
]
},
{
"id": 11,
"components": [
{ "id": 110, "name": "graphic card" },
{ "id": 322, "name": "motherboard" }
]
}
]
},
res = JSON.search( data, '//components[id=110]' );
res[0].name = 'video card';
Here is a working fiddle;
http://jsfiddle.net/g8fZw/
DefiantJS extends the global object JSON with the method "search" and returns an array with matches (empty array if no matches were found). You can try out the lib and XPath queries using the XPath Evaluator here:
http://www.defiantjs.com/#xpath_evaluator

Categories

Resources