For loop over array in array AngularJS - html

How do I iterate over this array in array in AngularJS Javascript code:
[[4,5,6,4,8.7]]

An array is an array.
Use Array.prototype.forEach for iteration.
In this case, each item is an array, and therefore you have an inner forEach as well.
Angular also has a method for forEach. It's called angular.forEach.
You can use it if you want to or need to support ancient browsers.
[[4,5,6,4,8.7]].forEach(function(arr){ arr.forEach(function(item){ console.log(item) }) } );
P.s. to avoid the smartass that is going to say that Array.prototype.forEach wont work on IE8, then it doesn't.

You can use 'angular.forEach'.
angular.forEach([[4,5,6,4,8.7]], function(arr){
angular.forEach(arr, function(value){
console.log(value);
})
});

Related

ember hasDirtyAttributes do not work with object (json)

I have a model:
export default Model.extend({
title: attr('string'),
attributes: attr('jsonb')
});
Where attributes is a custom json filed stored as jsonb in Postgres.
let say:
{
"name":"Bob",
"city":""
}
So I can easily manipulate attributes using template
<form.element .. #property="attributes.city"/> or model.set('attributes.city','city name')
Problem: hasDirtyAttributes do not changing because technically we have old object. But when I try to copy object let say
JSON.parse(JSON.stringify(this.get('attributes')) hasDirtyAttributes works as expected
So how to write some Mixin for a Model or other workaround which on the change of any attribute property will mark hasDirtyAttributes as true. I will update whole object so doesn't matter which property actually was changed.
Same problem: https://discuss.emberjs.com/t/hasdirtyattributes-do-not-work-with-nested-attributes-json-api/15592
existing solution doesn't work for me at all:
ember-dirtier
ember-data-relationship-tracker
ember-data-model-fragments (a lot of changes under the hood and broke my app)
Update:
Some not perfect idea that help better describe what I'm want to achieve:
Let say we adding observer to any object fileds:
export default Model.extend({
init: function(){
this._super();
this.set('_attributes', Object.assign({}, this.get('attributes'))); //copy original
Object.keys(this.get('attributes')).forEach((item) => {
this.addObserver('attributes.'+ item, this, this.objectObserver);
});
}
...
})
And observer:
objectObserver: function(model, filed){
let privateFiled = '_' + filed;
if (model.get(privateFiled) != model.get(filed)) { //compare with last state
model.set(privateFiled, this.get(filed));
model.set('attributes', Object.assign({}, this.get('attributes')) );
}
}
It's works, but when I change one filed in object due to copying object objectObserver faired again on every filed. So in this key changing every filed in object I mark observed filed as dirty
The further ember development will reduce using of event listener and two-way binding, actually Glimmer components supports only One-way Data Flow. So to be friendly with future versions of emberusing one-way data flow is good approach in this case to. So In my case as I use ember boostrap solution looks like
<form.element #controlType="textarea" #onChange={{action 'attributeChange'}}
where attributeChange action do all works.
New Glimmer / Octane style based on modifier and looks like:
{{!-- templates/components/child.hbs --}}
<button type="button" {{on "click" (fn #onClick 'Hello, moon!')}}>
Change value
</button>

Getting information from array of array

I've tried getting information with JSON only with one function, and it works fine. When it becomes two or more though it was pointed out that an array of array should be used.
How can you decode this information?
get.php
$response = array("home"=>$home, "topr"=>$top);
echo json_encode($response);
test.js
$(document).ready(function() {
$.get("php/get_ratings.php")
.done(function(data) {
var results = jQuery.parseJSON(data); // Should I change this?
$.each(results, function(i, value) { // Or this?
})
});
});
What PHP calls "arrays" are not what most languages call "arrays," including both JSON and JavaScript. Your response will be in this form:
{"home": something, "topr": something}
In your code:
No, you don't need to parse it, jQuery will do that for you if it's being sent correctly (e.g., with Content-Type: application/json).
You can access .homeand .topr properties on the object you receive.
E.g.:
$( document ).ready(function() {
$.get( "php/get_ratings.php")
.done(function(data) {
// use data.home and data.topr here
});
});
What you do with them depends on what they are, which you haven't shown. If they're numerically-index arrays (what most languages call arrays), your response will look like this:
{"home":["stuff","here"], "topr": ["stuff","here"]}
...and .home and .topr will be JavaScript arrays.
If they're PHP associative arrays like your top level thing, then they'll come through as objects, with properties named after the keys of the associative array.

Is there a way to print the json representation of an object to the browser in Polymer?

In AngularJS I would use:
<pre>{{object|json}}</pre>
Is there a way to do the same thing in PolymerJS?
The implementation of a custom json filter is quite simple:
<script>
PolymerExpressions.prototype.json = function(object) {
return JSON.stringify(object);
}
</script>
Then you can use {{object|json}} anywhere you like.
I don't think so out of the box, you could create a custom element and just render your object as:
JSON.stringify(object)

How to get a list via POST in Restangular?

Consider a REST URL like /api/users/findByCriteria which receives POSTed JSON that contains details of the criteria, and outputs a list of Users.
How would one call this with Restangular so that its results are similar to Restangulars getList()?
Restangular.all('users').post("findByCriteria", crit)... might work, but I don't know how to have Restangular recognize that the result will be a list of Users
Restangular.all('users').getListFromPOST("findByCriteria", crit)... would be nice to be able to do, but it doesn't exist.
Doing a GET instead of a POST isn't an option, because the criteria is complex.
Well,
I experience same problem and I workaround it with plain function, which return a plain array of objects. but it will remove all Restangular helper functions. So, you cant use it.
Code snippet:
Restangular.one('client').post('list',JSON.stringify({
offset: offset,
length: length
})).then(
function(data) {
$scope.clients = data.plain();
},
function(data) {
//error handling
}
);
You can get a POST to return a properly restangularized collection by setting a custom handler for OnElemRestangularized in a config block. This handler is called after the object has been Restangularized. isCollection is passed in to show if the obect was treated as a collection or single element. In the code below, if the object is an array, but was not treated as collection, it is restangularized again, as a collection. This adds all the restangular handlers to each element in the array.
let onElemR = (changedElem, isCollection, route, Restangular: restangular.IService) => {
if (Array.isArray(changedElem) && !isCollection ) {
return Restangular.restangularizeCollection(null, changedElem, changedElem.route);
}
return changedElem;
};
RestangularProvider.setOnElemRestangularized(onElemR);

Getting the last element from a JSON array in a Handlebars template

So, I found that array elements can be accessed in Handlebars using:
{{myArray.2.nestedObject}} and {{myArray.0.nestedObject}}
..to get the third and first elements for instance. (handlebars-access-array-item)
Is there a way to get the last element from an array?
I tried creating a helper for it:
Handlebars.registerHelper("lastElement", function(array) {
return array.last(); //Array.prototype extension
});
...and calling it as follows in the template:
{{lastElement myArray}} or even {{lastElement myArray.lastElement nestedArray}}
Sadly, this doesn't work. Helper functions return strings apparently. What I need is a way to be able to do this even with multi-dimensional arrays.
Should work, I've tested it.
Template:
{{last foo}}
Data:
{foo : [1,2,3,4,5,6]}
Helper:
Handlebars.registerHelper("last", function(array) {
return array[array.length-1];
});
The above piece of code works fine in all the cases. But if the array passed if a null array, possibility of the handlebar function throwing error is there. Instead perform a null check and then return the value accordingly.