How to iterate JsArray in Scala view page (value map is not a member of play.api.libs.json.JsArray) - arrays

I'm using JsArray on Scala view page, And I tried to iterate it using for loop, but throwing error on the Scala view page, Here I attached my code, how can I resolve it.
#(jsonArrValue: play.api.libs.json.JsArray)
<html>
<body>
<table>
<thead>
<tr>
<th>Details</th>
</tr>
</thead>
<tbody>
<tr>
#for(x <- jsonArrValue){
<td>#x</td>
}
</tr>
</tbody>
</table>
</body>
</html>
Error:
value map is not a member of play.api.libs.json.JsArray
jsonArrValue contains:
[{"empName":"xxx","age":"23","empNo":"123"},{"empName":"yyy","age":"24","empNo":"1234"}]

While the name JsArray may suggest it's a collection sort of thing, it's actually not. The definition:
case class JsArray(value: Seq[JsValue] = List()) extends JsValue with Product with Serializable
clearly shows it. That why for comprehension does not work.
And I think the best way to iterate it is call its value() method to convert to a Seq[JsValue], then use for comprehension.

Related

I am trying to execute multiple ng-repeat so that I can access a third level array in my json and display in a table but can't get this working

I am trying to nest ng-repeat but looks like I am not doing it correctly.
I need all the lineItem in the json to be displayed.
Since, json value I am trying to display is a 3rd level array, I tried nested
ng-repeat but does not work.
<table border="1" width="100%">
<tr>
<th>Id</th>
<th>materialNumber</th>
<th>quantity</th>
</tr>
<tbody ng-repeat="subConfig in values.subConfigs.subConfig">
<tr ng-repeat="lineItem in subConfig.lineItems.lineItem">
<td>{{lineItem.lineItemId}}</td>
<td>{{lineItem.materialNumber}}</td>
<td>{{lineItem.quantity}}</td>
</tr>
</tbody>
</table>
here is jsfiddle I tried:
Your json was not in correct format values should not be array also you need to change ng-repeat="s in values.subConfigs.subConfig"> to ng-repeat="s in values.configBOM.subConfigs.subConfig">
Something like
<tbody ng-repeat="s in values.configBOM.subConfigs.subConfig">
<tr ng-repeat="lineItem in s.lineItems.lineItem">
<td>{{lineItem.lineItemId}}</td>
<td>{{lineItem.materialNumber}}</td>
<td>{{lineItem.quantity}}</td>
</tr>
</tbody>
Here is working fiddle
Its a very minor mistake :
Please change your json to an object instead of an array , the format you have given is wrong .
So it should be :
$scope.values={} //whatever you want to write inside
instead of:
$scope.value=[];
Secondly while you are doing ng-repeat you have to change this line :
<tbody ng-repeat="subConfig in values.subConfigs.subConfig">
to :
<tbody ng-repeat="subConfig in values.configBOM.subConfigs.subConfig">

Colorize function not working after updating 2D Array

I am using a duo of ng-repeat's to create a matrix table, but after updating the data the coloring function (a simple return 'green' if the argument is above 0) stops working.
When I load the first (fake) data the colors work just fine, but after any updates it stops working. When initializing the 2d array it will always load and display properly. I have found no debug errors or problem with the logic.
Jfiddle
UPDATE**: I created a simple function that changes a few values in the 'original' 2D-array and I still face the problem with it not updating colors. I am pretty positive this is an AngularJS problem (shortcoming?) and not an issue with the data itself.
HTML
<!-- MATRIX TABLE -->
<div class="center w80" >
<div id = "MatrixTable2">
<table border="1">
<thead>
<tr>
<th></th> <!-- blank -->
<th ng-repeat="ppp in PlayerIDList">{{ppp.name}}</th>
</tr>
</thead>
<tbody>
<tr width="50px" ng-repeat="row in Matrix" >
<td class="rowlabel">{{PlayerIDList[$index].name}}</td>
<td width="50px" ng-repeat="col in row track by $index" ng-class="::funcGetColorByBool({{col}})">{{col}}</td>
</tr>
</tbody>
</table>
</div>
<!-- END MATRIX TABLE -->
I believe your problem is the class binding, the :: prefix means this expression is only evaluated once.
"::funcGetColorByBool({{col}})"
Also, you need to fix your expression to pass in the value of col:
from:
ng-class="::funcGetColorByBool({{col}})"
to:
ng-class="funcGetColorByBool(col)"
Here is a working plunker.

What is the best practice to show the data fetched by Laravel 4.2 from Database using 'ng-repeat' of AJS

I'm fetching data from the database using Laravel 4.2, it returns an array of JSON objects, then I pass that data to a view. But I'm unable to show it using Angular JS' ng-repeat directive. How can I do taht?
Note for Blade I'm using [[ ]], and for Angular JS I'm using {{ }}.
Controller of Laravel is given as Following:
class CountryController extends BaseController {
public function index()
{
return View::make('admin.country.show')
->with('countries', Country::all());// returns array of JASON objects
}
}
View of Laravel is given as follows:
<table class="table table-bordered">
<tr>
<th class="col-lg-2">Sr.No</th><th>Country</th>
</tr>
<!-- foreach($countries as $country) -->
<tr ng-repeat="country in $countries">
<td class="col-lg-2">{{country.id}}</td><td>{{country.country}}</td>
</tr>
<tr><td>{{query}}</td></tr>
<!--endforeach -->
</table>
{{countries}}
[[ $countries]]
{{countries}} of ajs not works but [[$countries]] works! How can I access $countries in AJS?
I don'n know that whether it's a good practice or not but I've found the solution which is given as follows:
<table class="table table-bordered">
<tr>
<th class="col-lg-2">Sr.No</th><th>Country</th>
</tr>
<tr ng-repeat="country in $countries">
<td class="col-lg-2">{{country.id}}</td><td>{{country.country}}</td>
</tr>
</table>
Instead of using
<tr ng-repeat="country in $countries">
I've used the
<?php echo("<tr ng-repeat='country in ". $countries. "'>"); ?>
It, after rendering becomes
<tr class="ng-scope" ng-repeat="country in [{"id":1,"countries":"Pakistan"},{"id":2,"countries":"Saudi Arbia"}]">
You can clearly see that an array of JSON object is returned by php, which now can easly be printed.
Note again: I don't know that it's best practice or not! I still would like to know the best practice.

How to get the selected item after filtering in angularjs?

I have the following:
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Url</th>
<th>Published</th>
<th>Import</th>
</tr>
</thead>
<tr ng-repeat="catalogObject in catalog | filter:catalogueSearchText |
orderBy:sortOrder:true"">
<td>{{catalogObject.name}}</td>
<td>{{catalogObject.url}}</td>
<td>{{catalogObject.published}}</td>
<td style="text-align:center">
<div class="btn btn-primary"
ng-click="ok(catalogObject.originalPosition)">✔</div></td>
</tr>
</table>
I have created the originalPosition property so that once I have filtered my catalog I know exactly what position the selected object is in the catalog scoped list.
Is there a better way than creating this additional property on my collection using a more declarative approach?
So basically I need a way to get access to the selected item once the original list has been filtered and sorted (before I just used $index in ng-click = "ok($index") however this index does not correspond to the original position of the elements in my catalog list).
You want to access the original object, but you already have this object!
All you have to do is make a small modification to your ok() function, so that it works for ok(catalogObject)

Getting the maximum date of a complex property

Using Angular $http, I have a model retrieved from a database. Its a Forum object that has Topics. Each topic has many Posts.
I am displaying a grid with showing |Topic Description|Count of Posts| Latest Post|
I have the first two working but I am not sure how to get at the data from the latest post (last column). A Post has a DatePosted property. I want to show the latest Post with info about the poster and the header etc.
Would this be a custom filter or is their a better way.
<div ng-controller="forumCtrl">
<h3>{{forum.ForumDescription}}</h3>
<h4></h4>
<table class="table table-condensed table-bordered table-hover table-striped">
<thead>
<tr>
<th>Topic</th>
<th>Threads</th>
<th>Latest Post</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="topic in forum.Topics">
<td>{{topic.TopicText}}</td>
<td>{{topic.Posts.length}}</td>
<td>{{Math.max(topic.Posts.PostDate)}}</td>
</tr>
</tbody>
</table>
You could either use the orderBy filter in the view, or have a function in the $scope that takes a Posts array and returns the latest Post, e.g.:
<!-- Approach 1 -->
<td>{{(topic.Posts | orderBy:'PostDate':true)[0].PostDate}}</td>
<!-- Approach 2 -->
<td>{{latestPost(topic.Posts).PostDate}}</td>
/* Approach 2 */
$scope.latestPost = function (posts) {
return posts.reduce(function (latest, current) {
return (current.PostDate > latest.PostDate) ? current : latest;
});
};
See, also, this short demo.
Notes:
1. You could alternatively define and use your own filter.
2. The above implementation are demos and do not take into account corner-cases, e.g. empty Posts etc.

Resources