VueJS sum pivot table - javascript

I am learning VueJS and am in the process of porting a very simple app I wrote in Laravel with blade as the template engine.
I am keeping the existing back end which consists of a simple restful api of 3 tables: Books, Places and a pivot Books_Places.
The json looks something like this:
books:
{
"id": 1,
"title": "foo bar",
"places": [
{
"id": 1,
"name": "library 1",
"pivot": {
"book_id": "1",
"place_id": "1",
"quantity": "50",
"id": 1
}
},
{
"id": 2,
"name": "library 2",
"pivot": {
"book_id": "1",
"place_id": "2",
"quantity": "75",
"id": 2
}
}
]
}
In blade I had the following line built into a "for book in books" cycle which I loved because of its simplicity:
{{ $book->places->sum('pivot.quantity') }}
I am trying to accomplish the same in VueJS but not sure what the simplest approach is, I'd appreciate your opinions.
Thanks!

You could create a method to sum up the quantities using Array#reduce:
methods: {
sumOfQuantities: function(book) {
return book.places.reduce(function(sum, next) {
return sum + Number(next.pivot.quantity);
}, 0);
}
}
Note: Since your quantity is a string, you need to convert it to a Number (e.g. using Number()).
You can then access it in your template using v-text for example:
<div v-for="book in books">
<div v-text="sumOfQuantities(book)"></div>
</div>

Related

JSON weird format access data

This is a JSON snip that is created in WooCommerce by a plugin that adds some metadata. I cannot change the formatting of this JSON because it is generated by a plugin. The problem is that the keys and the values are added in a weird way. I am iterating through the line_items and statically referencing this data which I don't want to do, I would like to know if there is a smart way to reference for example:
"key": "_cpo_product_id",
"value": "3572",
if this was formatted correctly it would be: "_cpo_product_id": "3572" and not have "value" as a key, and it would be accessed by: foo.line_items[i]._cpo_product_id
but with this configuration I am a bit lost, I am sure there is an easy way to find the value for a specific key. I am doing this on Google app scripts, but a solution in JavaScript should suffice.
JSON snip:
"line_items": [
{
"id": 749,
"name": "Dune",
"product_id": 3572,
"variation_id": 0,
"quantity": 1,
"tax_class": "",
"subtotal": "149.54",
"subtotal_tax": "31.40",
"total": "149.54",
"total_tax": "31.40",
"taxes": [
{
"id": 24,
"total": "31.403148",
"subtotal": "31.403148"
}
],
"meta_data": [
{
"id": 11919,
"key": "_cpo_product_id",
"value": "3572",
"display_key": "_cpo_product_id",
"display_value": "3572"
},
{
"id": 11920,
"key": "_add-to-cart",
"value": "3572",
"display_key": "_add-to-cart",
"display_value": "3572"
},

How can I .filter an object by elements within an array inside an object?

I've been playing around trying to learn in an API project using Postman and conducting tests using JavaScript. So far, I have succeeded with the help of reading on websites and watching YouTube videos. Of course, previous tests and playing around have been fairly easy but now I came to a stop. I really tried to figure this out for several weeks but I need further guidance, a push in the right direction or direct help.
What I'm trying to do is to filter out some of the response to only view objects that contain specific data.
To do that, I'm using a filter where I want all products containing a specific value inside an array "product_option_values".
My first approach was to see if I could sort products having any values from the first array, and it worked. It filters just fine.
var filterSmall = jsonData.products.filter(fs => fs.associations.product_option_values);
My next approach was to get to my goal of filtering out products according to specific values inside this array. I tried many simple .(dot) combinations and pointing to [index] to access it without any luck. (I must add that I know how to access this from a specific product, but that way doesn't work when filtering).
I've also tried other approaches such as:
var filterSmall = jsonData.products.filter(fs => fs.associations["product_option_values", 0, "name"] === "S");
and other similar combinations.
This is a very shortened sample of the structure of "products" which in its full form consists of 20 products and far more values inside of it:
{
"products": [
{
"id": 16,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Mountain fox notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "22"
},
{
"id": "23"
}
]
}
},
{
"id": 17,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Brown bear notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "23"
},
{
"id": "24"
}
]
}
}
]
}
and here is a small and expanded sample from product_option_values:
{
"product_option_values": [
{
"id": 1,
"id_attribute_group": "1",
"color": "",
"position": "0",
"name": "S"
},
{
"id": 2,
"id_attribute_group": "1",
"color": "",
"position": "1",
"name": "M"
},
{
"id": 3,
"id_attribute_group": "1",
"color": "",
"position": "2",
"name": "L"
}
]
}
How do I proceed? Did I do anything correct or even close to it?
Perhaps I've been staring at this for too long.
Thanks in advance.
If you want to compare nested attributes you have to transform the objects (e.g. by using a map operation), so that the relevant attributes are easily accessible for a comparison. If you want to filter by product_option_value id, you could do something like this:
const jsonData = {
"products": [
{
"id": 16,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Mountain fox notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "22"
},
{
"id": "23"
}
]
}
},
{
"id": 17,
"manufacturer_name": "Graphic Corner",
"quantity": "0",
"price": "12.900000",
"indexed": "1",
"name": "Brown bear notebook",
"associations": {
"categories": [
{
"id": "2"
},
{
"id": "6"
}
],
"product_option_values": [
{
"id": "23"
},
{
"id": "24"
}
]
}
}
]
};
const sample = {
"product_option_values": [
{
"id": 22,
"id_attribute_group": "1",
"color": "",
"position": "0",
"name": "S"
},
{
"id": 2,
"id_attribute_group": "1",
"color": "",
"position": "1",
"name": "M"
},
{
"id": 3,
"id_attribute_group": "1",
"color": "",
"position": "2",
"name": "L"
}
]
};
const ids = sample.product_option_values.map((el) => String(el.id));
console.log(ids);
const filtered = jsonData.products.filter((fs) => fs.associations.product_option_values.map((e) => e.id).some((f) => ids.includes(f)));
console.log(filtered);

Query with join between documents

I would like to create a view in CouchDb which contains some fields from multiple linked documents.
My documents are something like this:
/*Products:*/
{
"_id": "Products:ABC",
"doctype": "Products",
"productCode": "ABC",
"description": "The best product you ever seen",
"category_id": "Categories:1",
"brand_id": "Brands:52"
},
{
"_id": "Products:DEF",
"doctype": "Products",
"productCode": "DEF",
"description": "DEFinitely a good product",
"category_id": "Categories:2",
"brand_id": "Brands:53"
},
/*Categories*/
{
"_id": "Categories:1",
"categoryID": "1",
"description": "Awesome products"
},
{
"_id": "Categories:2",
"categoryID": "2",
"description": "Wonderful supplies"
},
/*Brands*/
{
"_id": "Brands:52",
"brandID": "52",
"description": "Best Items"
},
{
"_id": "Brands:53",
"brandID": "53",
"description": "Great Gadgets"
},
I would like to have a result like this:
/*View results: */
{
"id": "Products:ABC",
"key": "Products:ABC",
"value": {
"productCode": "ABC",
"description": "The best product you ever seen",
"category": {
"categoryID": "1",
"description": "Awesome products"
},
"brand": {
"brandID": "52",
"description": "Best Items"
}
}
},
{
"id": "Products:DEF",
"key": "Products:DEF",
"value": {
"productCode": "DEF",
"description": "DEFinitely a good product",
"category": {
"categoryID": "2",
"description": "Wonderful supplies"
},
"brand": {
"brandID": "53",
"description": "Great Gadgets"
}
}
},
The goal is to have a result that is a join between the three documents. Is it possibile?
As you can imagine I come from the SQL world, so maybe I am designing the database terribly wrong, so any advice on how to change the documents structure is welcome!
Thanks in advance!
Francesco
There are two ways to do this:
Use the query() API and linked documents (search the page for "linked documents")
Use the relational-pouch plugin
The advantage of the relational-pouch plugin is that, under the hood, it is faster than linked documents because it doesn't rely on building up a map/reduce index. The advantage of linked documents is that it is the more traditional way of solving this problem in CouchDB, and it doesn't rely on an extra plugin. Choose whichever one you like. :)
Edit: re-reading your question, I see you want to join 3 different document types together. Currently that is not possible with linked documents (you can only "join" two types), whereas it is possible with relational-pouch. So I guess that makes the decision easy. :)

Backbone , changing models attributes

In a collection i need to set the value to one of attributes, but i cant find the way how do it
products.models[i].set({'category.name':'some_value'})
the rest api looks like this
{
"category": {
"id": 3,
"name": "Drink",
"icon": "staging/main/category/icon-drinks.png"
},
"id": 1,
"name": "Sugar54",
"dashboard": 1,
"last_buy": "2013-10-02",
"price": "102",
"buy_period": 7
},
How do i do that ?
If you have complex nested models, I suggest you take a look at BackboneRelational.
Otherwise in your case, you should be fine with
products.models[i].get('category').name = 'some_value';
supposing that category is a normal object.

How to filter results from nested objects in angular

I have the nested objects in my angular like this
{
"name": "John"
"age" : "23"
subjects: [
{
"description":"Math"
"length":"1 month"
},
{
"description":"English"
"length":"1 month"
}
]
}
IN angular the filter works fine with name, age but how can i find those students whose subject description contains Math
The documentation page on filters has an interesting example.
In it, the ng-model of the search box is set to search.$ instead of search. This seems to be a wild card for matching.
Here's a jsFiddle for you. Type whatever into the search box and it will find the matching student.
<input id="txtSearch" type="text" ng-model="search.$" />
<ol>
<li ng-repeat="student in myData | filter:search">
{{student.name}}
{{student.subjects}}
</li>
</ol>
and the data model looks like this:
$scope.myData = [{
"name": "Student 1",
"age": "20",
subjects: [{
"description": "Math",
"length": "1 month"
}, {
"description": "English",
"length": "1 month"
}]
}, {
"name": "Student 2",
"age": "22",
subjects: [{
"description": "Economics",
"length": "1 month"
}, {
"description": "English",
"length": "3 months"
}]
}, {
"name": "Student 3",
"age": "23",
subjects: [{
"description": "Math",
"length": "4 months"
}, {
"description": "English",
"length": "6 months"
}]
}];
Not sure if this is really an Angular question - You need a way to parse the raw json data in javascript.
One way to do it is to use a functional library like Underscore, which provides functional like utilities to perform these kind of operations.
See http://jsfiddle.net/9W5YF/2/ for an example, and check http://underscorejs.org for documentation on underscore.
var studentsDoingMaths = _.filter(json, function (student) {
var doingMaths = doingSubject("Math");
return subjectSearch(student, doingMaths);});

Categories

Resources