I'm using angularfire for to save and display my user data. The form they fill out stacks or duplicates the data rather than updating. I only want one to display the most recent data, any ideas? I have it all contained in a panel and things like users name is listed 3 times.
app.controller('infoCtrl', ['$scope', '$location', '$firebaseArray', 'Auth',
function($scope, $location, $firebaseArray, Auth) {
this.userAuthData = Auth.$getAuth();
vm = this;
var ref = new Firebase('https://capstone-zhf.firebaseio.com/' + this.userAuthData.uid + '/surveyInfo');
ref.orderByChild('name').limitToLast(2).on("child_added", function(snapshot) {
});
vm.syncObject = $firebaseArray(ref);
var newInfo = {};
$scope.addInfo = function() {
vm.syncObject.$add({
q1: vm.newInfo.q1,
q2: vm.newInfo.q2,
q3: vm.newInfo.q3,
q4: vm.newInfo.q4,
q5: vm.newInfo.q5,
q6: vm.newInfo.q6,
q7: vm.newInfo.q7,
weight: vm.newInfo.weight,
height: vm.newInfo.height,
name: vm.newInfo.name
});
vm.newInfo = {};
};
Here is my HTML code
<table>
<tr ng-repeat="(id, info) in infoCtrl.syncObject">
<td class="panel-body">Goal: {{ info.q1 }}</td>
<td class="panel-body">{{ info.q2 }}</td>
<td class="panel-body">{{ info.q5 }}</td>
<td>
<button ng-click="editNew(info)">Edit</button>
</td>
<td>
<button ng-click="infoCtrl.syncObject.$remove(id)">x</button>
</td>
</tr>
</table>
Related
I've populated a table with data from a JSON file, and then when the user clicks on an item in the table, a container and it's fields display below and it SHOULD be populated with that specific data, though it isn't.
The function select is invoked through list-patents.htm which contains the table with a list of patents. I have used the $rootScope object so the function is accessible from multiple controllers i.e. patentDetailsCtrl
Why isn't my table in patent-item.htm being populated with the ng-repeat directive?
var app = angular.module('myApp', ['ngRoute', 'angularMoment', 'ui.router', "chart.js"]);
$stateProvider
.state("patents.list.item", {
url: "/patent-item",
templateUrl: "templates/patents/list/patent-item.htm",
params: {
id: null,
appNo: null,
clientRef: null,
costToRenew: null,
renewalDueDate: null,
basketStatus: null,
costBandEnd: null,
nextStage: null
},
controller: "patentDetailsCtrl"
})
app.run(function($rootScope) {
$rootScope.select = function() {
return $rootScope.patentItem = item;
}
});
app.controller('patentDetailsCtrl', ['$scope', '$http', function($scope, $http) {
$scope.selectedPatent = $scope.patentItem;
console.log($scope.selectedPatent);
}]);
list-patents.htm
<tbody>
<tr ng-repeat="x in patents">
<td ng-click="select(x)"><a ui-sref="patents.list.item({id: x.id, appNo: x.applicationNumber, clientRef: x.clientRef, costToRenew: x.costToRenew, renewalDueDate: x.renewalDueDate, basketStatus: x.basketStatus, costBandEnd: x.costBandEnd, nextStage: x.nextStage})">{{x.applicationNumber}}</a></td>
<td ng-bind="x.clientRef"></td>
<td ng-bind="x.costToRenew">$</td>
<td ng-bind="x.renewalDueDate"></td>
<td><button type="button" class="btn btn-danger" ng-click="remove(x.id)">Remove</button></td>
</tr>
</tbody>
patent-item.htm
<table>
<tbody>
<thead>
<tr>
<td>applicationNumber</td>
<td>clientRef</td>
<td>costToRenew</td>
<td>renewalDueDate</td>
<td>basketStatus</td>
<td>costBandEnd</td>
<td>nextStage</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in selectedPatent">
<td>{{x.applicationNumber}}</td>
<td>{{x.clientRef}}</td>
<td>{{x.costToRenew}}</td>
<td>{{x.renewalDueDate}}</td>
<td>{{x.basketStatus}}</td>
<td>{{x.costBandEnd}}</td>
<td>{{x.nextStage}}</td>
</tr>
</tbody>
</table>
</tbody>
You need to correct below points:
your $rootScope.select() method doesn't accept data (select(x)) passed from your list-patents.htm, So put item as param.,
Like : $rootScope.select = function(item) { \\ code
Sine you do ng-repeat on $rootScope.patentItem, then I guess you need to make it array, and push the passed data to it. (No need of return statement as well.)
So run block should be like :
app.run(function($rootScope) {
rootScope.patentItem = [];
$rootScope.select = function(item) {
$rootScope.patentItem.push(item);
}
});
See this Example Fiddle
To me it seems like you're trying to access the patentItem selected in your select function. If you're passing it to the $rootScope this way, you will also need to access it this way.
So change the line as follows...
$scope.selectedPatent = $rootScope.patentItem
I have a php api that returns a list of companies and a list of users,
Each user has a company_id assigned.
(Users : CustomerList) (Companies : CompanyList)
The companies have a company_id and company_name value.
I'm using resolve to get both these arrays.
When displaying the CustomerList, the company_id of the customer is displayed and everything is working fine.
But what i require is instead of the company_id being shown, I need the company_name being displayed in the CustomerList.
The company_id of the CustomerList is related to the id in the CompanyList.
Just that the company_name is contained in the companyList and not in the CustomerList. But the ID's are related and contained in the userList.
I need to get the company_name of the id that's in CustomerList and display it in the view.
resolve: { userList:function($http,$stateParams){
return $http.post('/api/get_users.php',{role:$stateParams.role},{headers: { 'Content-Type': 'application/x-www-form-urlencoded' }})
.then(function(response){
console.log(response);
return response.data.data;
})
},
companyList:function($http,$stateParams){
return $http.get('/api/get_companies.php')
.then(function(response){
console.log(response);
return response.data.data;
})
}
}
controller("CustomerList", function($scope,$location,$http,$stateParams,userList,companyList){
$scope.customers = userList;
$scope.companies = companyList;
})
VIEW
<table>
<thead>
<tr>
<th>Username</th>
<th>Company Name</th>
<th>Contact Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="customer in customers">
<td>{{ customer.username }}</td>
<td>{{ customer.company_id }}</td>
<td>{{ customer.contact_name }}</td>
</tr>
</tbody>
</table>
the customer.company_id is related to the ID in the companyList , i need to return the companyList.company_name instead of showing the company ID in the customers.
Thanks in advance for any help.
You need to join them.
So you need to create a new object with will contain the username, contact_name, company_name and other properties you need. You need to use the map() which will return an array of new objects. With username and contract_name it is easy, just assign the properties to the new created object. With company_name, we need to find the appropriete company and assign it's name to the newly created object.
Working Example with simple data, which joins two arrays based on the id.
var app = angular.module('app', []);
app.controller('ctrl', ['$scope', function($scope){
var userList = [
{username: 'A user', contact_name: 'A contract', company_id: 1},
{username: 'B user', contact_name: 'B contract', company_id: 2},
{username: 'C user', contact_name: 'C contract', company_id: 3},
];
var companyList = [
{id: 1, name: 'A Company'},
{id: 2, name: 'B Company'},
{id: 3, name: 'C Company'},
];
$scope.customers = userList.map(item => {
var foundCompany = companyList.find(company => company.id === item.company_id);
return {
username: item.username,
contact_name: item.contact_name,
company_name: foundCompany ? foundCompany.name : ''
};
});
$scope.companies = companyList;
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app" ng-controller="ctrl">
<table>
<thead>
<tr>
<th>Username</th>
<th>Company Name</th>
<th>Contact Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="customer in customers">
<td>{{ customer.username }}</td>
<td>{{ customer.company_name }}</td>
<td>{{ customer.contact_name }}</td>
</tr>
</tbody>
</table>
</body>
You can structure your companies list in such a way that each object in list is key value pair with key being id of company and value being complete object of company details and then access it easily.
eg
$scope.companies = {
{
"companyId1" : {
"name" : "companyName",
"field2" : "vlue2"
}
},
{
"companyId2" : {
"name" : "companyName2",
"field2" : "vlue2"
}
}
}
and then in your html access it using
{{companies[customer.company_id].name}}
This will work for you
map your userList so that it will contain companyName
var mappedCustomerList= userList.map(function(user){
var user=userWithCompanyName;
userWithCompanyName['companyName']=
companyList[companyList.findIndex(function(company){return company['id']==user['company_id']})].companyName;
return userWithCompanyName;
});
$scope.customerList=mappedCustomerList;
so then from your view you can access companyName
<td>{{customer.companyName}}</td>
I have a JSON object that does not have proper data. So i want to replace the obtained value with one from a lookup table, but I'm not sure how to replace the value of the data corresponding to the lookup table.
lookupTable = {
"pizza": function() {
console.log("food");
},
"house": function() {
console.log("building");
},
"air": function() {
console.log("nothing");
}
};
$scope.value =lookupTable["pizza"]()
my html file has
<tr ng-repeat="x in names">
<td>{{ x.lookupTable["pizza"]() }}</td>
My code is at http://plnkr.co/edit/w4lOFVRo9vSi8vqfbpXV?p=preview
Any help is appreciated!
Here are some problems in your code from the link you provided:
Functions on the lookupTable is not returning anything as pointed out in the previous answers.
lookupTable is not a property of $scope.names so using x.lookupTable is invalid.
To make it work, you should:
The functions from lookupTable should return the actual values instead of using console.log
Bind lookupTable to $scope
Use lookupTable directly inside the view as it is bound to $scope
Here is the relevant code:
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td>{{ lookupTable[x.Name]() }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("data.json")
.then(function(response) {
$scope.names = response.data.records;
});
$scope.lookupTable = {
"pizza": function() {
return 'food';
},
"house": function() {
return 'building';
},
"air": function() {
return "nothing";
}
};
});
</script>
Your code is very confused. I tried to edit your plunker, maybe is easier to see that to explain.
<!DOCTYPE html>
<html>
<scriptsrc="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="customersCtrl">
<table>
<tr ng-repeat="x in names">
<td>{{ lookupTable[x.Name] }}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("data.json")
.then(function(response) {
$scope.names = response.data.records;
});
lookupTable = {
"pizza": "food",
"house": "building",
"air": "nothing"
};
$scope.lookupTable = lookupTable;
$scope.value = lookupTable["pizza"]
console.log(lookupTable["house"])
});
</script>
Looking at your code, I am not sure what you want to achieve.
The ng-repeat gives you three objects out of names, but none of them has a lookupTable member, so {{ x.lookupTable["pizza"] }} fails silently.
You can make it visible, if you just bind to {{ x }}
I am using AngularJS and to show products in a table to my users. Here the user can filter the table using categories or other key words. But the user has to be able to edit the product table, like editing product names or prices and these data has to be altered also in my database of course. Now I am using xeditable which works great and I am able to get the productID which I have to change and the function to change the data gets called but that's it. Here can you see my code:
AngularJS
categorieFilter = angular.module("categorieFilter", ["xeditable"])
categorieFilter.run(function(editableOptions) {
editableOptions.theme = 'bs3'; // bootstrap3 theme. Can be also 'bs2', 'default'
});
categorieFilter.controller("catFilter", ["$scope", "store", function($scope, store){
$scope.search = "";
$scope.products = [];
$scope.categories = [];
$scope.postname = function ($prodid){
$http.get('api/editproduct/id/$scope.product.name')
.success(function(results){
})
.error(function(data, status){
console.error("Category add error: ", status, data);
});
};
store.getCategories().then(function(data){
$scope.categories = data;
})
store.getProducts().then(function(data){
$scope.products = data;
})
$scope.filterProductsByCats = function(category){
$scope.search = category;
};
}])
categorieFilter.factory('store', function($http, $q){
function _getCategory (){
var deferred = $q.defer();
$http.get('api/categories').success(function (data) {
deferred.resolve(data);
})
return deferred.promise;
}
function _getProducts (){
var deferred = $q.defer();
var prods = [];
$http.get('api/products').success(function (data) {
for(var i = 0;i<data.length;i++)
{
prods[i] = {id: data[i][0], name: data[i][1], category: data[i][3], price: data[i][2]};
}
deferred.resolve(prods);
})
return deferred.promise;
}
return {
getCategories: _getCategory,
getProducts : _getProducts
};
});
HTML
<div ng-app="categorieFilter" ng-cloak="" ng-controller="catFilter">
<div class="input-group">
<input type="text" name="table_search" class="form-control input-sm pull-right" ng-model="search" placeholder="Search"/>
<div class="input-group-btn">
<button class="btn btn-sm btn-default">
<i class="fa fa-search"></i>
</button>
</div>
</div>
<div>
<input type="submit" class="btn btn-success" style="margin:10px; width:30%;" ng-repeat="cat in categories" ng-click="filterProductsByCats(cat.categoryName)" value="{{cat.categoryName}}">
</div>
<table class="table table-hover">
<tr style="background-color:#ddd;">
<th colspan="4" style="text-align:left; font-size:16px;"> Category </th>
<th colspan="4" style="text-align:left; font-size:16px;"> Product </th>
<th colspan="4" style="text-align:left; font-size:16px;"> Price </th>
</tr>
<tr ng-repeat="product in products | filter:search | orderBy: 'category'">
<td colspan="4">{{product.category}}</td>
<td colspan="4" onaftersave="postname(product.id)" editable-text="product.name">{{product.name}}</td>
<td colspan="4" editable-text="product.price">{{product.price}}</td>
</tr>
</table>
I(m getting error:
ReferenceError: $http is not defined
So what am I doing wrong here? How can I update the required data in my database after changing it in my table using angular and xeditable..?
I updated my controller and function like this and now it works fine:
categorieFilter.controller("catFilter", ["$scope", "$http", "store", function($scope, $http, store){
$scope.search = "";
$scope.products = [];
$scope.categories = [];
$scope.postname = function ($prodid, $prodname){
alert($prodname);
$http.get('api/editproduct/'+$prodid+'/'+$prodname)
.success(function(results){
})
.error(function(data, status){
console.error("Category add error: ", status, data);
});
};
I got this directive:
.directive('studentTable', [function() {
return {
restrict: 'A',
replace: true,
scope: {
students: "=",
collapsedTableRows: "="
},
templateUrl: 'partials/studentTable.html',
link: function(scope, elem, attrs) {
...
}
}
}
Template:
<table class="table">
<thead>
<tr>
<th><b>Name</b></th>
<th><b>Surname</b></th>
<th><b>Group</b></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="student in students track by $index">
<td>{{ student.name }}</td>
<td>{{ student.surname }}</td>
<td>{{ student.group }}</td>
</tr>
</tbody>
</table>
Use directive in my html like this:
<div student-table students="students"
collapsedTableRows="collapsedTableRows"></div>
And the parent controller:
.controller('SchoolController', ['$scope', 'User', function($scope, User){
$scope.students = [];
$scope.collapsedTableRows = [];
$scope.search = function(value) {
if(value) {
var orgId = $state.params.id;
var search = User.searchByOrg(orgId, value);
search.success(function (data) {
$scope.students = data;
$scope.collapsedTableRows = [];
_(data).forEach(function () {
$scope.collapsedTableRows.push(true);
});
});
}
}
}])
Now at the beginnig, the table is empty, because no users in students array. After I click search, and get list of students object, I put them to scope variable, but the directive does not update, neither it find change in model (scope.$watch('students',...). What am I missing?
P.S. If I simulate the data using $httpBackend, directive works as it should.
Please make sure that data object returning array of student because somtimes you have to use data.data that simple demo should helps you:
http://plnkr.co/edit/UMHfzD4oSCv27PnD6Y6v?p=preview
$http.get('studen.json').then(function(students) {
$scope.students = students.data; //<-students.data here
},
function(msg) {
console.log(msg)
})
You should try changing the controller this way
...
$scope.$apply(function() {
$scope.students = data;
})
...
This will start a digest loop, if it's not already in progress.
Another form that will do almost the same thing is this:
...
$scope.students = data;
$scope.$digest()
...
PS:
The first method is just a wrapper that execute a $rootScope.$digest() after evaluating the function, considering that a $digest evaluates the current scope and all it's children calling it on the $rootScope is pretty heavy.
So the second method should be preferred if it works.