Converting table from HTML to Javascript array in AngularJS - angularjs

This plunk is my attempt to convert an HTML table to a Javascript array using only AngularJS/jqLite. I can get the head and body from the table, however when I try to get the rows from the body object I get the following error (see the console): tbody.children is not a function. How to fix this?
Javascript
var table = angular.element($scope.t);
var thead = table.children()[0];
var tbody = table.children()[1];
console.log(tbody.children());

I've not used this API before, but a quick check reveals that you lose the angular.element benefits when you pick the children(). You can wrap it again like this to access children method again:
var table = angular.element($scope.t)
var thead = angular.element(table.children()[0])
var tbody = angular.element(table.children()[1])
console.log(tbody.children());

Related

Angularjs Directive -Get Element By ID

I have tried everything.
Instead of this:
var table = e.target.nextElementSibling
I want to use this:
var table = angular.element(document).find('#tabletarget');
or:
var table = angular.element(document).find('tabletarget');
But it's giving me an error as undefined. How can I select this specific table instead of blindly seeking for the next element?
angular.element(document.getElementByID('tabletarget'));
OR
angular.element(document.querySelector('#tabletarget'));

Compiling an element with AngularJs attributes after the page is loaded

I need to create multiple <a ng-click="controller.doThat(X)"> elemets, based on a response from some $http call. And add them to an element designated by its id attribute.
I am using AngularJs v1.6.4. Please help.
var newElem = $compile(t)($scope);
document.getElementById("designatedDiv").appendChild(newElem[0]);
does the job as long as t is a string of a single element:
var t = "try and press <a ng-click=\"controller.doThat(X)\">here</a> and see..."
will result in:
Error: [jqLite:nosel] http://errors.angularjs.org/1.6.4/jqLite/nosel
at angular.min.js:6
BUT if you redo the last example as following:
var t = "<span>try and press </span><a ng-click=\"controller.doThat(X)\">here</a><span> and see...</span>"
var newElem = $compile(t)($scope);
for (i=0;i<newElem.length;i++)
document.getElementById("designatedDiv").appendChild(newElem[i]);
then it works as expected.

how to retrieve data nested in two collections from firebase with angular

I'm new in Angular - Firebase development, and I am having problems to understand how to retrieve data nested in two collections.
I have a collection named "Orders", which includes a field call "auth", which is the user ID, and I have another collection that is the "User Profile", wich it's $id is the value of "auth". Inside the User Profile I have a field named roomNumber, and it's content I that I want to retrieve every time I read, in ng-repeat of the Orders.
In my view I was trying to do something like this :
<tr ng-repeat="item in items | filter: searchKeyword ">
<td align="left">{{item.$id}} - {{roomNumber(item.$id)}}</td></tr>
roomNumber is a function in my controller
$scope.roomNumber = function(id) {
var rootRef = new Firebase("https://xxxx-fire-yyyy.firebaseio.com/userProfile"+ '/' + id);
$scope.userdet = $firebaseArray(rootRef);
rootRef.on("value", function(rootSnapshot) {
var key = rootSnapshot.key();
var childKey = rootSnapshot.child("room").val();
console.log("room ", childKey)
});
return childKey
}
When I run this code and see results in my js console, strange things happend:
1. It repeat a lot of times
2. I can never get the childKey value
I have been reading Firebase documentation, but really I do not understand how to do this "silly" thing, does anybody give me a tip of how to do it?
When you bind a function to the $scope and call it within the html it expects to get an answer back right away when called. So when you query firebase and it takes its sweet time getting you back an answer, angularjs has already gotten an answer of undefined from the function.
So what is happening is that you are registering a callback when you provide the function to rootRef.on and then right after you register the callback you are returning the value of childKey. Unfortunately, childKey only gets set by the callback function (which firebase hasn't executed yet). Therefore angularjs gets an answer of undefined from your roomNumber function.
In order to make this work, you are going to have to get the room numbers beforehand and then probably add them to each of your items in $scope.items then use
<td align="left">{{item.$id}} - {{item.room}}</td></tr>
instead of
<td align="left">{{item.$id}} - {{roomNumber(item.$id)}}</td></tr>
To load all the room numbers you could call some function like this one after $scope.items has loaded
for (var i = 0; i < $scope.items.length; i++) {
var rootRef = new Firebase("https://xxxx-fire-yyyy.firebaseio.com/userProfile"+ '/' + $scope.items[i].$id);
$scope.userdet = $firebaseArray(rootRef);
rootRef.on("value", function(rootSnapshot) {
var key = rootSnapshot.key();
var childKey = rootSnapshot.val().room;
$scope.items[i].room = childKey;
});
}
It would change each of the items to have a reference to the room. Unfortunately, that list wouldn't update as the data updates, so the better solution would be to do that same query in whatever function was getting your items from the server and add the room to each item as it was being added to the items list.
To fix the issue with childKey not reading you need to use this:
var childKey = rootSnapshot.val().room;
instead of this:
var childKey = rootSnapshot.child("room").val();
console.log("room ", childKey)
Reference: https://www.firebase.com/docs/web/guide/retrieving-data.html

Render XML in table using AngularJs

Please help me to render below XML data in the form of table using AngularJS
<EmployeeDetail>
<employeeID>1564654</employeeID>
<employeeName>Vinit</employeeName>
<emailID>xyz#email.com</emailID>
</EmployeeDetail>
<EmployeeDetail>
<employeeID>14654</employeeID>
<employeeName>Varun</employeeName>
<emailID>xyz#email.com</emailID>
</EmployeeDetail>
Help me in this case as soon as possible
$http.get('someUrlforXml').then(function(response) {
$scope.EmployeeDetail = [];
/*setting up the response*/
var data = x2js.xml_str2json(response.data);
$scope.EmployeeDetail = data.EmployeeDetail;
if it is not work for you try this link

Angular use $cacheFactory data in controller

I hava a ProdCache service used to cache a products array.
...
var products = ProdCache.get('all');
if(typeof products == 'undefined'){
products = Product.query();
ProdCache.put('all',products);
}
If I put products on the scope the products are shown as expected, but I need only a few products to be shown.
My try:
$scope.related = (function(){
var res = [];
if(products.length>0){
for (var i = 0, key; i < 3; i++) {
key = Math.floor(Math.random() * products.length);
res.push(products[key]);
}
}
return res;
})();
That function wont work the first time because the xhr request is being processed and the returned data is not reactive.
The proper way is to use filters docs here and here.
Assuming the filter you wrote is a mock, and you need a complex filter, you just have to create a filter function at $scope and reference it at ng-repeat expression:
$scope.isRelated = function isRelatedFilter(item) {
// if return is true, the item is included.
return item.someProperty === 'someCriteria';
}
<span ng-repeat="product in products | filter:isRelated">...</span>
The someCriteria could be another $scope/controller property or defined by a service. If you need custom parameters, than you can't use the filter filter and should create your own. Take a look at the docs.
Without the HTML code you are using for binding, it's a little difficult to determine how you are using your $scope.related function. However, if the only problem you are having is that, when the data comes back from the xhr request, the UI does not update, it is likely that your $digest phase has already ended and therefore the binding to $scope.related is not causing the function to re-fire until the next $digest phase.
This would probably work to handle the issue you are having:
...
var products = ProdCache.get('all');
if(typeof products == 'undefined'){
products = Product.query();
ProdCache.put('all',products);
// Add this line to force re-digest if needed
if(!$scope.$$phase) $scope.$digest();
}
Without seeing the HTML though, I'm not sure that this will solve your issue. If not, post a plunker so we can see the problem better.

Resources