I'm doing an employees list that is loaded from SQLite database. I don't know why my list is empty, but I can see via JSON.stringify that data is comming.
I'm using AngularJS and Cordova Framework. Debugging with Ripple.
listEmployees.html
<div data-role="page" apply-jq-mobile>
<div data-theme="a" data-role="header">
<h3>
Header
</h3>
</div>
<div data-role="content">
<div class="ui-grid-a">
<div class="ui-block-a">
</div>
<div class="ui-block-b">
<a data-role="button" href="#/new" data-icon="plus" data-iconpos="left">
New
</a>
</div>
</div>
<input type="text" ng-model="search" class="search-query" placeholder="Search">
<ul data-role="listview" data-divider-theme="b" data-inset="true">
<li data-role="list-divider" role="heading">
Employees
</li>
<li data-theme="c" ng-repeat="employee in employees">
{{employee.name}}
</li>
</ul>
</div>
</div>
EmployeeCtrl
function EmployeeCtrl($scope, Employee){
$scope.employees = Employee.getAllEmployees();
$scope.saveEmployee = function(id) {
if(id){
//TODO
} else {
Employee.addEmployee($scope.employee);
}
}
}
Employee
app.factory('Employee', function() {
var data = {};
data.addEmployee = function(_employee, callback) {
var employee = new Employee();
employee = _employee;
DbService.db.employees.add(employee);
DbService.db.saveChanges(callback);
}
data.getAllEmployees = function() {
DbService.db.employees.toArray(function(employees) {
console.log(JSON.stringify(employees));
return employees;
});
};
return data;
});
I think you need to use promises. Your call to db is asynchronous and therefore view is getting rendered before your data arrives.
data.getAllEmployees = function() {
var $d = $q.defer();
DbService.db.employees.toArray(function(employees) {
console.log(JSON.stringify(employees));
$d.resolve(employees);
});
return $d.promise;
};
Angular templating system wait for all the promises to get resolved before rendering. So I think this will solve your problem.
So, I solved it.
function EmployeeCtrl($scope, Employee){
Employee.getAllEmployees(function(employees){
$scope.employees = employees;
$scope.$apply();
});
}
.
app.factory('Employee', function() {
var data = {};
data.getAllEmployees = function(callback) {
DbService.db.employees.toArray(function(employees) {
callback(employees);
});
};
return data;
});
Thank you all!
Related
We have a iOnic based project and during check out users can add new address to their account.
This is what my controller file look like
$scope.addAddress = function() {
$scope.showLoading();
addressService.addUserAddress($scope.userDetails.userID, $scope.addAddressdata.houseNo, $scope.addAddressdata.street, $scope.addAddressdata.AddDesc, $scope.addAddressdata.LID)
.success(function(response) {
console.log(response);
$scope.hideLoading();
$scope.closeModal();
$scope.getAllAddress();
});
};
$scope.getAllAddress = function() {
addressService.getAllLocations()
.success(function(response) {
$scope.locations = response;
$scope.hideLoading();
});
};
And this is what my services file look like
function() {
"use strict";
var myApp = angular.module('jobolo');
myApp.service('addressService', ['$http', 'appVariableService', function($http, appVariableService) {
var addressService = this;
addressService.getAllLocations = function() {
var data = {
appid: appVariableService.get('appId')
};
return $http.post(appVariableService.get('baseURL') + 'useraddress/getMyLocation', data);
};
addressService.getUserAddress = function(userId) {
return $http.get(appVariableService.get('baseURL') + 'useraddress/myaddress/' + userId, {cache:false});
};
addressService.addUserAddress = function(userId, houseNo, street, adddesc, lid) {
var data = {
appid: appVariableService.get('appId'),
userid: userId,
houseno: houseNo,
street: street,
adddesc: adddesc,
lid: lid,
};
return $http.post(appVariableService.get('baseURL') + 'useraddress/adAdd' , data);
};
}]);
})();
When I add a new address it does add to the database but isn't showing in list. I tried adding $scope.refreshList(); to the code too. When I log out and come back it does show up. Thank you for your help in advance
View Codes are
<ion-view class="main-content">
<ion-nav-buttons side="secondary">
<button menu-toggle="right" class="button button-icon icon ion-navicon"></button>
</ion-nav-buttons>
<div class="bar bar-subheader">
<h2 class="title">Select Address</h2>
</div>
<ion-content class="has-subheader" scroll="true" overflow-scroll="true" style="bottom:57px">
<div class="list">
<ion-radio
ng-model="data.selectedAddress"
ng-value="address"
ng-repeat="address in userAddresses"
class="radio-nowrap"
>
House No. {{address.HouseNo}}, {{address.Street}}, {{address.AddDesc}}, {{address.AreaName}}, {{address.City}}
</ion-radio>
</div>
<!-- <div class="row">
<div class="col location-form">
<button class="button" type="button" ng-click="openModal()">Add New Address</button>
</div>
</div> -->
</ion-content>
<div class="row" style="position: absolute;bottom: 0;padding:0">
<div class="col location-form">
<button class="button" type="button" ng-click="openModal()">Add New Address</button>
</div>
<div class="col location-form">
<button class="button" type="button" ng-disabled="!data.selectedAddress" ng-click="selectAddress(data.selectedAddress)">Select Address</button>
</div>
</div>
I have a dropdown menu and I want to show and hide DIVs based on the selection of that dropdown menu. I have duplicated fields in templates because I do not know the better way to handle, so if someone can suggest me simpler way to code, I will appreciate it.
The code I wrote is below
Template(html)
<div id="pack-method" class="col-sm-30">
{{ form.item_packmethod|as_crispy_field }}
</div>
<div id="hidden2-1">
<div class="col-sm-20">
{{form.pallet_count|as_crispy_field}}
</div>
<div class="col-sm-20">
{{form.pallet_width|as_crispy_field}}
</div>
<div class="col-sm-20">
{{form.pallet_height|as_crispy_field}}
</div>
</div>
<div id="hidden2-2">
<div class="col-sm-20">
{{form.pallet_count|as_crispy_field}}
</div>
<div class="col-sm-20">
{{form.pallet_width|as_crispy_field}}
</div>
<div class="col-sm-20">
{{form.pallet_height|as_crispy_field}}
</div>
<div class="col-sm-20">
{{form.pallet_depth|as_crispy_field}}
</div>
</div>
<script type="text/javascript">
$('#hidden2-1').css({
'display': 'none'
});
$('#hidden2-2').css({
'display': 'none'
});
$('#pack-method').on('change', function() {
if (this.value === 'Pallet') {
$('#hidden2-1').show();
$('#hidden2-2').hide();
}
else if ($(this).val() == 'Rack') {
$('#hidden2-1').hide();
$('#hidden2-2').show();
}
else if ($(this).val() == 'Box') {
$('#hidden2-1').hide();
$('#hidden2-2').show();
}
else {
$('#hidden2-1').hide();
$('#hidden2-2').hide();
}
});
</script>
Forms.py
BLANK_CHOICE = (('', '----------'),)
PALLET = 'Pallet'
RACK = 'Rack'
BOX = 'Box'
PACK_TYPE = (
(PALLET, 'Pallet'),
(RACK, 'Rack'),
(BOX, 'Box'),
)
item_packmethod = forms.ChoiceField(label="Pack Method", choices = BLANK_CHOICE + PACK_TYPE,required=False)
I have solved the problem.
For those who might be interested, I changed
$('#pack-method').on('change', function() {
if (this.value === 'Pallet') {
$('#hidden2-1').show();
$('#hidden2-2').hide();
}
...
}
to
$('select').on('change', function() {
var a = $(this).val();
if (a === 'Pallet') {
$('#hidden2-1').show();
$('#hidden2-2').hide();
}
...
}
I'm new with ember. I try to display a simple select box that contains age value.
This is my controler :
App.HomeController = Ember.ObjectController.extend({
ages : function() {
var ages = [];
for(var i = 18; i <= 99; i++) {
ages.push(i);
}
return ages;
}
});
This is my view :
<div class="container" id="main">
<div class="row">
<form class="form-horizontal" role="form">
<div class="form-group">
<label for="name" class="col-xs-2 control-label">Name : </label>
<div class="col-xs-10">
{{input type="text" name="name" value=firstname autofocus="true"}}
</div>
</div>
<div class="form-group">
<label for="age" class="col-xs-2 control-label">Age : </label>
<div class="col-xs-10">
{{view "select" content=ages}}
</div>
</div>
</form>
</div>
i get this error when i refresh browser :
Error: Assertion Failed: The value that #each loops over must be an Array. You passed function () {
var ages = [];
for(var i = 18; i <= 99; i++) {
ages.push(i);
}
return ages;
}
Anyone can tell me how i can do that?
Your ages function resolved by handlebars. If you want to use it as a property add this to your function so you can use it in handlebars and also I would recommend you to use Ember.A() instead of javascript array.
ages : function() {
var ages = Ember.A();
for(var i = 18; i <= 99; i++) {
ages.pushObject(i);
}
return ages;
}.property()
Not tested code by the way
Im new to Ember and I am trying to create a record by submitting a form. This is the code I've written so far:
App.CharactersNewRoute = Ember.Route.extend({
model: function() {
return this.store.createRecord('character', {name: '', race: ''});
}
});
<form {{action "createCharacter" on="submit"}}>
<div class="form-group">
<label>Name</label>
{{input value=characterName class="form-control"}}
</div>
<div class="form-group">
<label>Race</label>
{{input id=characterRace class="form-control"}}
</div>
{{#link-to 'characters'}}<button class="btn btn-default">Back</button>{{/link-to}}
<button class="btn btn-default" type="submit">Create</button>
</form>
App.CharactersNewController = Ember.ObjectController.extend({
actions: {
createCharacter: function() {
var name = this.get('characterName'),
race = this.get('characterRace');
if (!name || !race) { return false }
// create new character
var character = this.store.createRecord('character', {
name: name,
race: race
});
this.set('characterName', '');
this.set('characterRace', '');
character.save();
}
}
})
Right now, the code stops at the var character = this.store.createRecord line in the controller, but no errors are raised in the console
Thanks
I'm building an app that has the following code:
Routes:
App.Router.map(function() {
this.resource('gradebooks', function() {
this.resource('gradebook', { path: ':gradebook_id' });
});
});
App.IndexRoute = Em.Route.extend({
redirect: function() {
this.transitionTo('gradebooks');
}
})
App.GradebooksRoute = Em.Route.extend({
setupController: function(controller, model) {
Em.$.getJSON('/data/gradebooks/get', function(data) {
controller.set('model', data);
});
}
});
App.GradebookRoute = Em.Route.extend({
model: function(params) {
var id = params.gradebook_id;
return Em.$.getJSON('/data/gradebooks/get/' + id);
}
})
Controllers:
App.GradebooksController = Em.ArrayController.extend({
isActive: false,
actions: {
createGradebook: function(newTitle) {
var self = this;
if(newTitle.trim()) {
Em.$.get('/data/gradebooks/add/' + newTitle, {}, function(json) {
Em.$('#create-gradebook-modal').modal('hide').find('input').val('');
self.transitionToRoute('gradebook', json.id);
}, 'json');
}
}
}
});
Templates (gradebooks.hbs):
<div class="sidebar">
<div class="btn-container">
<button class="btn btn-block btn-info" data-toggle="modal" data-target="#create-gradebook-modal">
<i class="fa fa-book"></i>
Create Gradebook
</button>
</div>
<ul>
{{#each}}
<li {{bind-attr class="isActive:active"}}>
{{#link-to "gradebook" _id}}
{{title}}
{{/link-to}}
</li>
{{/each}}
</ul>
</div>
<div class="content">
<div class="container-fluid">
{{outlet}}
</div>
</div>
Templates (gradebook.hbs):
<h1>{{title}} <small>{{_id}}</small></h1>
<div class="btn-container">
<button class="btn btn-default"><i class="fa fa-pencil"></i> Rename</button>
<button class="btn btn-danger"><i class="fa fa-trash-o"></i> Trash</button>
</div>
What I'm having trouble with is under the GradebooksController.actions.createGradebook, I send a request to create the model and then I transition to the gradebook I just created. The creation and transition works just fine, but I want the sidebar (gradebooks.hbs) to show the newly created gradebook.
I think it has something to do with updating the model in the GradebooksRoute. How can I make it fetch for the models from the server again after creating a gradebook.
To elaborate on #fanta's comment, you'll want to do something like this:
App.GradebooksController = Em.ArrayController.extend({
isActive: false,
actions: {
createGradebook: function(newTitle) {
var self = this;
if(newTitle.trim()) {
var gradebook = Em.$.getJSON('/data/gradebooks/add/' + newTitle, {}, function(json) {
Em.$('#create-gradebook-modal').modal('hide').find('input').val('');
self.transitionToRoute('gradebook', json.id);
}, 'json');
self.get('content').pushObject(gradebook);
}
}
}
});