Angular Doesn't Update ng-show - html

I have a table from which I have the representation of data that gets updated every 10 seconds or so, represented by the "current" list. As you can see in the code snippet below, the two ng-show's depend on the Status value of an object. I know that the list is getting updated with new values, so that the second ng-show should be showing and not the first, but it only updates when I refresh the page, not automatically. Shouldn't the ng-show's get updated automatically when the value of the Status field of the object gets changed?
<table>
<tr ng-repeat="object in current">
<td>Name: {{object.Name}} <br /> Status: {{object.StatusMessage}}<br /> ID: {{object.ID}} <br /> User: {{object.UserName}}</td>
<td>
<div ng-show="object.Status == 2 || object.Status == 3">
<img ng-src="{{getScreenshot(object.Name)}}" style="width: 500px; height: 300px">
</div>
<div ng-show="object.Status < 2 || object.Status > 3" style="font-size: large; font-weight: bold">
Screenshot not available.
</div>
</td>
</tr>
</table>

You can apply AngularJS $digest() function.
For more information about $digest() function go to AngularJS $watch() , $digest() and $apply()
You need to modify your controller code to something like this:
var app = angular.module('test', []);
app.controller('TestCtrl', function ($scope) {
$scope.testValue = 0;
setInterval(function() {
console.log($scope.testValue++);
$scope.$apply()
}, 500);
});
Jsfiddle: Link

Related

How to load Blob images in angular from phpmyadmin table

I created a function and set a get method to receive all the data from my table.
However I can't display images on browser. I have tried all the "solutions" but nothing seems to work.
This is what I currently have
<tbody>
<tr *ngFor="let obj of dataArr">
<td>{{obj.name}}</td>
<td>{{obj.price}}</td>
<td>
<img src="data:image/png;base64,{{obj.img}}"/>
</td>
</tr>
</tbody>
Name and price are displayed fine.
This is the data that I receive when I console log:
0: {id: 2, name: "nesto", price: "6", img: "ÿØÿàJFIFÿáExifII*ÿá…"QD¢%(DJ"QD¢%(DJ"QD¢%(DJ"QD¢/ÿÙ"}
Probably you're looking for this:
<img src="data:image/png;base64,{{
btoa(obj.img) /* or window.btoa(obj.img) try both */
}}"/>
I advise you to create a route which retrieves the file from database:
// routes.php
Route::get('files/{record_id}', function($record_id){
$Model = \EloquentModel::firstOrFail($record_id, ['img']);
return response($Model->img)->header('Content-Type', 'image/png');
});
// angular file
<img src="/files/{{ obj.id }}">

How do I get rows from a list(table) in a protractor e2e test?

The list in question is a table generated by a reactive angular form which does not have a specific ID. Following code is used to generate the list in angular part:
<p-table id='paragraphList' *ngIf="paragraphsObs | async; else loading"
[value]="paragraphsObs | async"
selectionMode="single" (onRowSelect)="select($event)"
scrollable="true">
<ng-template pTemplate="header">
<tr> ...header... </tr>
</ng-template>
<ng-template pTemplate="body" let-paragraph let-rowData>
<tr [pSelectableRow]="rowData">
<td width="15%">{{paragraph.cell1}}</td>
<td width="10%">{{paragraph.cell2}}</td>
<td width="31%">{{paragraph.cell3}}</td>
<td width="11%">{{paragraph.cell4 | dateTransform: helperService.MM_DD_YYYY_HH_MM_A_Z_DATE_PATTERN}}
</td>
<td width="11%">{{paragraph.cell5}}</td>
<td width="11%">{{paragraph.cell6 | dateTransform: helperService.MM_DD_YYYY_HH_MM_A_Z_DATE_PATTERN}}
</td>
<td width="11%">{{paragraph.cell7}}</td>
</tr>
</ng-template>
</p-table>
The corresponding table generated at the front-end has the following html source:
<p-table _ngcontent-c6="" id="paragraphList" scrollable="true" selectionmode="single" ng-reflect-selection-mode="single" ng-reflect-scrollable="true" class="ng-star-inserted" ng-reflect-value="[object Object],[object Object">
<div class="ui-table ui-widget ui-table-hoverable-rows" ng-reflect-ng-class="[object Object]">
<div class="ui-table-scrollable-wrapper ng-star-inserted">
<div class="ui-table-scrollable-view" ng-reflect-frozen="false">
<div class="ui-table-scrollable-header ui-widget-header">...header...</div>
<div class="ui-table-scrollable-body">
<table class="ui-table-scrollable-body-table" ng-reflect-klass="ui-table-scrollable-body-table" ng-reflect-ng-class="[object Object]">
<tbody class="ui-table-tbody" ng-reflect-template="[object Object]">
<tr _ngcontent-c6="" ng-reflect-data="[object Object]" class="ng-star-inserted">...</tr>
<tr _ngcontent-c6="" ng-reflect-data="[object Object]" class="ng-star-inserted">...</tr>
...
</tbody>
</table>
<div class="ui-table-virtual-scroller"></div>
</div>
</div>
</div>
</div>
</p-table>
I want to reach to those inner elements and get them as a list. I have tried using class names with element and all locators, to get the elements but to no avail. Then I tried using tag names to reach to those elements but that too doesn't seem to work.
This following small snippet returns 0 for the count of elements that I try to obtain from the list.
element(by.id('paragraphList')).element(by.css('.ui-table-scrollable-body-table'))
.all(by.tagName('tr')).count().then(function (result) {
console.log(result);
});
Any help would be appreciated. Thanks
Considering above is your full rendered HTML..
The code below will give an Array of arrays, where each array would be containing texts from all the cells of a row.
Explanation:
The code has three functions,
populateData() - is the driving function where we pass the resolved list of rows.
Then _populateRows() and _populateCells() run recursively to gather the text from the cells. This is also possible to do with a loop (as protractor queues the promises by itself) but I like keeping things clear on my end. _populateRows() recur on rows and _populateCells() recur on cells of each row. (more in comments)
Note This first thing which you should do before implementing this is: check the count() (or .length of resolvedRows) of element.all(by.css('#paragraphList table tbody tr')). As basically this was your original question I believe. Now If you have a count, then you can go with this solution or whatever suites your need.
let allRows = element.all(by.css(`#paragraphList table tbody tr`)); //will have all the rows.
allRows.then((rowsResolved) => {
// now have all the rows
PO.populateData(rowsResolved).then((allData) => {console.log(allData)}) // should be an Array od arrays, each array would be containing texts from all the cells.
// Considering you have a Page Object and added the functions below in the Page Object.
// Page Object is nothing but another class where we keep our utility methods
})
// driving function
populateData(rowsResolved) {
let data = [];
return this._populateRows(0, rowsResolved, data);
}
// calls itself recursively to loop over the rows
private _populateRows(index, rowsResolved, data) {
if (index >= rowsResolved.length) {
let defer = protractor.promise.defer();
defer.fulfill(data);
return defer.promise; // so that it is chainable even if I don't have any rows
}
let cells = element.all(by.css(`#paragraphList table tbody tr:nth-child(${index + 1}) td`));
cells.then((cellsResolved) => {
let cellData = [];
if (cellsResolved.length) {
data.push(cellData);
}
this._populateCells(0, cellsResolved, cellData);
return this._populateRows(index + 1, rowsResolved, data);
})
}
// calls itself recursively to loop over all the cells ofeach row.
private _populateCells(index, cellsResolved, cellData) {
if (index >= cellsResolved.length) {
let defer = protractor.promise.defer();
defer.fulfill(cellData);
return defer.promise; // so that it is chainable even if I don't have any cells(that would be an incorrect structure though, if a row exists then cells have to exist )
}
cellsResolved[index].getText().then((cellValue) => {
cellData.push(cellValue)
});
return this._populateCells(index + 1, cellsResolved, cellData);
}

How to print data in html using ng-repeat angularjs

I have json data in controller as response. I have to print that data in html.
for that I have done as below:
In my controller
.controller('DataImportControl', ['$scope','$http', '$location', '$rootScope' , function($scope, $http, $location, $rootScope) {
console.log(" In dataimportCtrl");
$scope.readCustomer = function(){
console.log("in read customer");
$http.post('/custimport').success(function(response) {
console.log("in controller");
console.log("controller:"+response);
$scope.data=response;
}).error(function(response) {
console.error("error in posting");
});
};
}])
My html code:
<html>
<head>
<script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body>
<div ng-app="" ng-controller="DataImportControl">
<form ng-submit="readCustomer()">
<button type="submit" >Submit</button>
</form>
<table class="table">
<thead>
<tr>
<th>Code exists in customer master</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="cust in data ">
<td>{{cust.customer_code}}</td>
</tr>
</tbody>
</table>
</div>
<div >
</div>
</body>
</html>
My json data as response in controller :
{"jarray":[{"customer_name":["Ankita"],"customer_code":["c501"]}]}
My question is how to print json data in html using ng-repeat in my case?
Thanks in advance...
I'm assuming you want to print out the actual object, in that case just do
{{cust | json}}
Wrap it in pre tags to have it prettified.
The data being returned from your service is strangely formatted. I would assume you have multiple records being returned, but you are only showing one in this example.
The record you are showing here is an object, with an array as one of the properties. It is not clear if your object has multiple arrays, or if this array has multiple customer objects embedded in it. However, I worked up a quick plunker showing how to iterate through in both situations.
first, if you intend to iterate through data directly, and data will hold multiple arrays, you would use the (key, value) syntax, since data itself is an object and not an array.
<div ng-repeat="(key, value) in data">
key: {{key}}
<br/>value: {{value}}
<div ng-repeat="customer in value">
Customer name: {{customer.customer_name}}
<br/>Customer code: {{customer.customer_code}}
</div>
</div>
However, if your data is only returning a single object property, jarray, and you will always be iterating through this same property, the outer ng-repeat is unnecessary:
<div ng-repeat="customer in data.jarray">
Customer name: {{customer.customer_name}}
<br/>Customer code: {{customer.customer_code}}
</div>
you may want to clean up your service, either in angular or on your server, and remove jarray all together, if it doesn't hold a specific significance to the data.
http://plnkr.co/edit/Nq5Bo18Pdj4yLQ13hnrJ?p=preview

Get the parent index of the array angularjs

I searching and I found out that this code is what I need right now. But there is something wrong about it. When I clicked the alertme button it's alert is -1 which is wrong. When I click 1 Brick med it's alert -1 it should be 0 because the no and name is in sectionA. When I want t click 3 Frank Joemar Timbang it should alert 1 because he is in sectionB? Aney help? suggestions? TIA
var stud = angular.module("stud", []);
stud.controller("StudentsController", function ($scope) {
'use strict';
$scope.alertMe = function (studentGroup) {
alert($scope.students.indexOf(studentGroup));
};
$scope.sectionA = [
{
no:1,
name:'Brick Med',
},
{
no:2,
name: 'Colin Christopher',
},
];
$scope.sectionB = [
{
no:3,
name: 'Frank Joemar Timbang',
},
{
no:4,
name: 'Curtis Zaymond',
}
];
$scope.students = [
$scope.sectionA,
$scope.sectionB
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html data-ng-app="stud">
<head lang="en">
<meta charset="utf-8">
<title>Students</title>
</head>
<body data-ng-controller="StudentsController" data-ng-init="init()">
<div id="container">
</div>
<div class="container-table">
<table border="1" width="100%">
<thead>
<tr>
<td>Students</td>
<td>Alert</td>
</tr>
</thead>
<tbody ng-repeat="studentGroup in students">
<tr ng-repeat="student in studentGroup">
<td>{{student.no}} {{student.name}}</td>
<td><button ng-click="alertMe($parent.$index)">Alert me!</button></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
Okay so your problem is that you are using indexOf() when you want to just be using studentGroup as the index.
$scope.alertMe = function (studentGroup) {
alert($scope.students[studentGroup]); // returns object object in your array
alert($scope.students[studentGroup][0]); /// returns sectionA object1
alert($scope.students[studentGroup][0].name); /// returns sectionA object1 name
};
And I fixed up your html so it is easier to read but your original stuff should still work.
<tbody ng-repeat="studentGroup in students" ng-init="studentsIndex = $index">
<tr ng-repeat="student in studentGroup">
<td>{{student.no}} {{student.name}}</td>
<td><button ng-click="alertMe(studentsIndex)">Alert me!</button></td>
</tr>
</tbody>
If this isn't what you want and you really want to alert the index, let me explain how indexOf works. That method will take a search parameter, and that is used to search an array for that element data. It is returning -1 right now because you give it the index and it searches for that index as the element data in index 0 and 1. Steps: Does whatever index = $scope.sectionA , Nope move on, Does whatever index = $scope.sectionB, nope move on. Done, did not find search parameter return -1.
The problem is with the indexOf. studentGroup is set correctly to 0 for the first 2 rows and 1 for the next 2. If you want the section array you should use
$scope.alertMe = function (studentGroup) {
alert($scope.students[studentGroup]);
};

Knockout Clone Whole Item In foreach

I am trying to clone elements when clicking a button. I was trying to use ko.toJS. On page load it works fine, but when I want clone the items, it is unable to bind the items (like, value, Text, etc.).
Here is the HTML:
<div class="stockItems-inner" data-bind="foreach: StockItems">
<div data-bind="if: Type=='Input'">
<div class="stock_container_input">
<input type="text" data-bind="value: Value" />
</div>
</div>
<div data-bind="if: Type=='Radio'">
<div class="stock_container_control">
<div data-bind="foreach: Options">
<div class="stockLbl">
<input type="radio" data-bind="text: Text, checked:$parent.Value, attr:{'id':Id, 'name': $parent.Text, 'value': Value}" />
<label data-bind="attr:{'for':Id}, text: Text"></label>
</div>
</div>
</div>
</div>
</div>
<div class="addItem">
<button type="button" data-bind="click: CloneItem"><img src="images/add.png" alt="" /></button>
</div>
The View Model:
ConfigurationStockViewModel = function() {
var self = this;
this.StockItems = ko.observableArray();
this.ApplyData = function(data){
self.StockItems(data.Items);
}
this.CloneItem = function(StockItems){
self.StockItems.push(ko.toJS(StockItems));
};
};
When clicking the button, an error is thrown: Unable to process binding. I am using JSON data for binding.
Not exactly sure what end result you want without working code, but sounds like you want to clone the last item in array and add to array?
If so, I think you have an error - your add button click binding will never pass anything to the function you defined, since it is outside the foreach. You need something like this:
this.CloneItem = function() {
var toClone = self.StockItems()[self.StockItems().length - 1]
self.StockItems.push(toClone);
};
Here is a simplified example without radio buttons, etc:
http://jsfiddle.net/5J47L/