How to push named Json Array Into Json Object - angularjs

I want to push below data. I want order the items, it consists of following fields:
var OrderItem = {"itemid":item.itemid,"itemname":item.itemname,"qty":1,"itemprice":item.itemprice};
But I want to Store Like this
{
"Items": [
{
"itemid": 50,
"itemname": "sample",
"itemprice": 124,
"qty": 1
},
{
"itemid": 52,
"itemname": "sample",
"itemprice": 124,
"qty": 1
}
]
}
Controllers:
$scope.addnew=function(item){
var OrderItem= {"itemid":item.itemid,"itemname":item.itemname,"qty":1,"itemprice":item.itemprice};
NewOrderService.addOrderitems(OrderItem);
}
}
Services:
servctrl.service("NewOrderService", function(NewOrderFactory) {
this.addOrderitems = function(orderitemnew) {
NewOrderFactory.AddOrdernew(orderitemnew);
}
});
Factorys:
factmodule.factory("NewOrderFactory",function(){
var orderitemsnew=[];
return {
AddOrdernew:function(orderitemnew){
orderitemsnew.push(orderitemnew);
}
}
});
How to Achieve this?

probably like this?
factmodule.factory("NewOrderFactory",function(){
var orderitemsnew={
items = [];
};
return{
AddOrdernew:function(orderitemnew){
orderitemsnew.items.push(orderitemnew);
},
getOrderItemsNewList: function() {
return orderitemsnew;
}
};
});

Related

Issues with transforming array data

I'm trying to transform the following JSON array data structure -
From
[
{
"date": "2019-01-01",
"marks": [
{
"quantity": {
"shoes": 1,
"belt": 2,
"socks": 3
}
}
]
},
{
"date": "2019-01-02",
"marks": [
{
"quantity": {
"shoes": 4,
"belt": 5,
"socks": 6
}
}
]
}
]
To
rows: [
{
values: [ '2019-01-01', 1, 2, 3]
},
{
values: [ '2019-01-02', 4, 5, 6]
}
]
The code that I was able to try so far is this -
function myFunction() {
var response = [
{
"date": "2019-01-01",
"marks": [
{
"quantity": {
"shoes": 1,
"belt": 2,
"socks": 3
}
}
]
},
{
"date": "2019-01-02",
"marks": [
{
"quantity": {
"shoes": 4,
"belt": 5,
"socks": 6
}
}
]
}
];
var transform = response.map(function(dailyMarks) {
var row = [];
Object.keys(response).asArray().forEach(function (field) {
switch (field) {
case 'shoes':
return row.push(dailyMarks.shoes);
case 'belt':
return row.push(dailyMarks.belt);
case 'socks':
return row.push(dailyMarks.socks);
case 'date':
return row.push(dailyMarks.date);
default:
return row.push('');
}
});
return { values: row };
});
Logger.log(transform);
}
However, I'm running into this error -
TypeError: Cannot find function asArray in object 1,2. (line XX, file "Code")
Pretty sure I'm doing something wrong but have not been able to figure out where.
Objective is simply to transform the aforementioned data structure - approach doesn't really matter.
Any help would be highly appreciated! Thanks.
In ES5,
var arr1 = [
{
date: '2019-01-01',
marks: [
{
quantity: {
shoes: 1,
belt: 2,
socks: 3,
},
},
],
},
{
date: '2019-01-02',
marks: [
{
quantity: {
shoes: 4,
belt: 5,
socks: 6,
},
},
],
},
];
var out = [];
arr1.forEach(function(obj) {
obj.marks.forEach(function(mark) {
out.push({
values: [obj.date].concat(
Object.keys(mark.quantity).map(function(key) {
return mark.quantity[key];
})
),
});
});
});
console.log({ rows: out });
You could take an array of keys for the order and flatmap the marks array.
var data = [{ date: "2019-01-01", marks: [{ quantity: { shoes: 1, belt: 2, socks: 3 } }] }, { date: "2019-01-02", marks: [{ quantity: { shoes: 4, belt: 5, socks: 6 } }] }],
keys = ['shoes', 'belt', 'socks'],
rows = data.map(({ date, marks }) =>
({ values: [date, ...marks.flatMap(({ quantity }) => keys.map(k => quantity[k]))] })),
result = { rows };
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
let x = products.map(p=>{
return p.marks.reduce((t,m)=>{
t.push({ values: [p.date, ...Object.entries(m.quantity).map(([key, value]) => value)]})
return t;
},[])
}
).flat(2)
console.log(x)
var list=[{"date":"2019-01-01","marks":[{"quantity":{"shoes":1,"belt":2,"socks":3}}]},{"date":"2019-01-02","marks":[{"quantity":{"shoes":4,"belt":5,"socks":6}}]}];
let result = list.map(( {date, marks} ) => { return {value: [date, ...Object.values(marks[0].quantity)]};});
let wrap = {rows: result};
console.log(wrap);

how to use Immutability helper to update a nested object within an array?

Inside reducer, given a state object:
var state = {
"data": [{
"subset": [{
"id": 1
}, {
"id": 2
}]
}, {
"subset": [{
"id": 10
}, {
"id": 11
}, {
"id": 12
}]
}]
}
As you can see, the data is a nested array, with arrays in each of its elements.
Knowning that action.indexToUpdate will be a index for data, I want to update data[action.indexToUpdate].subset to a new array programmatically. For example, if action.indexToUpdate = 0, then data[0] will be updated from
[{"id":1},{"id":2}]
to
[{"id":4},{"id":5}]
In order to do so, I have:
let newSubset = [{"id":4},{"id":5}]
let newState = update(state.data[action.indexToUpdate], {
subset: {
newSubset,
},
})
But when I executed this, it returns error:
TypeError: value is undefined
on the update founction.
I have been looking at the react ducomentation here: https://facebook.github.io/react/docs/update.html but I couldn't really figure out how to do it. Please advise!
Your update will look like
var obj = {"state" : {
"data": [{
"subset": [{
"id": 1
}, {
"id": 2
}]
}, {
"subset": [{
"id": 10
}, {
"id": 11
}, {
"id": 12
}]
}]
}}
return update(obj, {
"state" : {
"data": {
[action.indexToUpdate]: {
"subset": {
$set: [newSubset]
}
}
}
}
})
In case there are other fields in subset, but you only wish to the change the fields at specific index containing other keys, you would write
return update(obj, {
"state" : {
"data": {
[action.indexToUpdate]: {
"subset": {
[id]: {$merge: newSubset}
}
}
}
}
})

Ace editor autocomplete uploads extra-records

I added ui-ace editor to the my application with angular. Instead of requesting words every time, I get a json 1 time, during application initiation.
Example of json-file:
[
{
"Word": "Do {int} + {int}",
"Meta": "Implemented"
},
{
"Word": "Line3",
"Meta": "Not-implemented"
},
{
"Word": "Line2",
"Meta": "Not-implemented"
},
{
"Word": "Line4",
"Meta": "Not-implemented"
},
{
"Word": "444",
"Meta": "Not-implemented"
},
{
"Word": "E1",
"Meta": "Not-implemented"
},
{
"Word": "E2",
"Meta": "Not-implemented"
},
{
"Word": "E1Try",
"Meta": "Not-implemented"
},
{
"Word": "E3",
"Meta": "Not-implemented"
},
{
"Word": "E4444",
"Meta": "Not-implemented"
}
]
The issue is that some of words are listed in autocomplete more than ones, take a look on a screenshot: http://take.ms/N8BFZ .
Here's how I load ace-editor, where ctrl.listStepLines is an object which contains json-response from API:
$scope.aceLoaded = function(_editor){
// Editor part
var _session = _editor.getSession();
var _renderer = _editor.renderer;
_editor.$blockScrolling = Infinity;
_editor.setOptions({
minLines: 10,
maxLines: 40,
wrap: true,
firstLineNumber: 1,
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true
})
var langTools = ace.require("ace/ext/language_tools");
var rhymeCompleter = {
getCompletions: function (editor, session, pos, prefix, callback) {
if (prefix.length === 0) { callback(null, []); return }
callback(null, ctrl.listStepLines.map(function (ea) {
return { name: ea.Word, value: ea.Word, meta: ea.Meta }
}));
}
}
langTools.addCompleter(rhymeCompleter);
};
The issue was that angularjs loaded my function a lot of times and ace editor had 14 similar completers. I refactored my code and create a separate function for completer adding which is called only one time.
ctrl.addAutoCompleter();
function init() {
ctrl.addAutoCompleter = function () {
var langTools = ace.require("ace/ext/language_tools");
var stepLineCompleter = {
getCompletions: function (_editor, session, pos, prefix, callback) {
if (prefix.length === 0) { callback(null, []); return }
callback(null, ctrl.listStepLines.map(function (ea) {
return { name: ea.Word, value: ea.Word, meta: ea.Meta }
}));
}
}
langTools.addCompleter(stepLineCompleter);
}
};

Order by Object key in ng-repeat

How can I order by key as integer?
I have the following Object;
$scope.data = {
"0": { data: "ZERO" },
"1": { data: "ONE" },
"2": { data: "TWO" },
"3": { data: "TREE" },
"5": { data: "FIVE" },
"6": { data: "SIX" },
"10":{ data: "TEN" },
"11": { data: "ELEVEN" },
"12": { data: "TWELVE" },
"13": { data: "THIRTEEN" },
"20": { data: "TWENTY"}
}
HTML:
<div ng-repeat="(key,value) in data">
The current output order is 1,10,11,12,13,14,2,20,3,4,5,6
But I want 1,2,3,4,5,6,10,11,12,13,14,20
| orderBy:key
don't work for me.
Any ideas?
Thanks!
An option would be use an intermediate filter.
PLUNK AND Code Snippet
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.template = {
"0": { data: "ZERO" },
"1": { data: "ONE" },
"2": { data: "TWO" },
"3": { data: "TREE" },
"5": { data: "FIVE" },
"6": { data: "SIX" },
"10":{ data: "TEN" },
"11": { data: "ELEVEN" },
"12": { data: "TWELVE" },
"13": { data: "THIRTEEN" },
"20": { data: "TWENTY"}
}
});
app.filter('toArray', function() { return function(obj) {
if (!(obj instanceof Object)) return obj;
return _.map(obj, function(val, key) {
return Object.defineProperty(val, '$key', {__proto__: null, value: key});
});
}});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore.js"></script>
<body ng-app="app" ng-controller="MainCtrl">
<div ng-repeat="(key, value) in template| toArray | orderBy:key">{{key}} : {{value.$key}} : {{value.data}}</div>
<body>
NOTE:
The above filter requires Underscore.js, if you don't use it, can rewrite the filter.
I think it sorts itself out with a conversion to an array. pun intended.
var obj = {"3": {three:3}, 2: {two:2}, "5": {five:5}, 4: {four:4},
1: {one:1}, 6: {six:6}, 10: {ten:10}, 11:{eleven:11}
}
$scope.arr = [];
for (var o in obj)
$scope.arr.push(obj[o])
app.filter('orderObjectBy', [function() {
return (filterObj, prop) => {
let arr = []
//below is the loadash function you can use for in also
_.forEach(filterObj, function(value, key) {
arr.push({
key: key,
value: value
});
});
let sortedArr = _.sortBy(arr, val => val.value[prop]);
for (let variableKey in filterObj) {
if (filterObj.hasOwnProperty(variableKey)) {
delete filterObj[variableKey];
}
}
for (let data of sortedArr) {
filterObj[data.key] = data.value;
}
return filterObj;
}
}])

$filter with custom function in angular

How I can create a $filter with custom function to determining if match ?
This is a json sample with structure:
$scope.routes =[
{
"id": 0,
"name": "Rosa Barnes",
"origin": [
{
"address": [
{
"locality": "Madrid",
"country": "ES"
}
]
}
]
},
{
"id": 1,
"name": "Wright Montoya",
"origin": [
{
"address": [
{
"locality": "London",
"country": "UK"
}
]
}
]
},
{
"id": 2,
"name": "Pearson Johns",
"origin": [
{
"address": [
{
"locality": "London",
"country": "UK"
}
]
}
]
}
];
I want a $filter that passing one country, match in origin.address.country , is possible?
I proved this code but not works:
$scope.routesToShow = $filter('filter')($scope.routes, {origin.address.country: "UK"});
Here there are a demo:
http://jsfiddle.net/86U29/43/
Thanks
What you need is a custom filter. It also looks like you might need to tweak your data structure too.
Take a look at this:
app.filter('CustomFilter', function () {
function parseString(propertyString) {
return propertyString.split(".");
}
function getValue(element, propertyArray) {
var value = element;
propertyArray.forEach(function (property) {
value = value[property];
});
return value;
}
return function (input, propertyString, target) {
var properties = parseString(propertyString);
return input.filter(function (item) {
return getValue(item, properties) == target;
});
}
});
You could use this filter, like this:
$scope.routesToShow = $filter('CustomFilter')($scope.routes, 'origin.address.country', 'UK');
Here is an updated jsfiddle (notice the updated data structure): http://jsfiddle.net/moderndegree/86U29/44/
You can find more information on creating custom filters here:
https://docs.angularjs.org/guide/filter#creating-custom-filters
Simply.
var filter = function(obj){
return obj.origin[0].address[0].country === 'UK';
}
$scope.routesToShow = $filter('filter')($scope.routes, filter);

Resources