Angular js: Iterate over list in view (ng-foreach) - javascript

I am getting json data in server response and return that to $scope.questions
I want to access this questions data in step1.html file.
app.js
(function () {
"use strict";
var app = angular.module("autoQuote",["ui.router","ngResource"]);
app.config(["$stateProvider","$urlRouterProvider", function($stateProvider,$urlRouterProvider){
$urlRouterProvider.otherwise("/");
$stateProvider
.state("step1", {
url : "/",
templateUrl : "easyquote/step1.html",
controller: "questionsCtrl",
})
.state("step2", {
url : "/step2",
templateUrl : "easyquote/step2.html",
controller: "questionsCtrl",
})
}]
);
}());
autoQuoteCtrl.js
(function () {
"use strict";
angular
.module("autoQuote")
.controller("questionsCtrl",["$scope","$http","$state",questionsCtrl]);
function questionsCtrl($scope,$http,$state) {
$http.get('rc1/getQuestions/' + $state.current.name)
.then(function(response) {
$scope.questions = response.data;
});
}
}());
step1.html
<div ng-controller="autoQuoteCtrl">
<form name="DTOstep1" ng-submit="onSubmit()">
<label>Email: </label><input type="text" name="email" id="email" />
<br><br>
<table ng-repeat="questions in que">
<tr>
<td>{{que.QuestionData._attributeName}}</td>
<td></td>
<tr>
</table>
<input type="submit" value="Save" />
</form>
</div>

Your usage of ng-repeat is the wrong way round. It should be like this:
<table ng-repeat="que in questions">

HTML
<table ng-repeat="questions in que">
<tr>
<td>{{questions._any_name}}</td>
<td></td>
<tr>
</table>

Related

Controller reading component data

My idea is to create a big form from separated components. So this is my main template:
<form novalidate>
<div class="row">
<user></user>
</div>
<button type="button" class="btn btn-default" ng-click="submit()"> Submit </button>
</form>
and its controller (the template is binded from ui route config to the controller)
(function () {
'use strict';
angular.module('app')
.controller('formCtrl', formCtrl);
function formCtrl ($scope) {
$scope.submit = function() {
console.log("read data");
}
}
})();
Now, the user component:
(function () {
'use strict';
var module = angular.module('app.user');
module.component("user", {
templateUrl: "app/user/user.html",
controllerAs: "model",
controller: function () {
var model = this;
model.user = {};
}
});
})();
and the user template:
<form novalidate>
<form-group>
<label for="inputUser"> Name <label>
<input ng-model="model.user.name" id="inputUser" type="text" placeholder="User"/>
</form-group>
<form-group>
<label for="inputUser"> Email <label>
<input ng-model="model.user.email" id="inputUser" type="email" placeholder="Email"/>
</form-group>
<div>
{{model.user | json}}
</div>
</form>
Now I want to be able to read user data when the user do the submit. How can I do it?
When using components, depending on the type of component (smart or dumb), you have to emit an output to the parent controller to handle such thing. But in this case, you can use ngModel to handle a model and change it on the parent from within the component. For example:
Working snippet:
angular.module('app', [])
.controller('formCtrl', function($scope) {
$scope.user = {};
$scope.submit = function() {
console.log($scope.user);
}
})
.component("user", {
bindings: {
user: '=ngModel'
},
templateUrl: "app/user/user.html",
controllerAs: "model",
controller: function() {}
});
angular.element(function() {
angular.bootstrap(document, ['app']);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.min.js"></script>
<form novalidate ng-controller="formCtrl">
<div class="row">
<user ng-model="user"></user>
</div>
<button type="button" class="btn btn-default" ng-click="submit()">Submit</button>
</form>
<script type="text/ng-template" id="app/user/user.html">
<form novalidate>
<div>
<label for="inputUser">Name
<label>
<input ng-model="model.user.name" id="inputUser" type="text" placeholder="User" />
</div>
<div>
<label for="inputUser">Email
<label>
<input ng-model="model.user.email" id="inputUser" type="email" placeholder="Email" />
</div>
<div>
{{ model.user | json }}
</div>
</form>
</script>
A possible solution would be $$childTail. So if I want to access to user:
$scope.$$childTail.model.user

Angularjs Cannot read property 'id' of undefined

I am new to angularjs, I'm trying to create a webapp that can access data from server and post the data to the server. But I'm facing issues, what I did in my application, I have created module,service,view and controller in separate files. I'm unable to access and post data to the server. Can anyone help me.
home.js(controller file)
var myapp = angular.module('demo').controller("homeController", function($scope,myService){
var userArray = {
Id:$scope.user.id,
Model:$scope.user.model,
Name:$scope.user.name,
Color:$scope.user.color,
Price: $scope.user.price
};
myService.async().then(function(d){
$scope.hello=d;
});
$scope.push = function(userArray){
myService.saveUser(userArray).then(function(response){
console.log("inserted");
});
}
});
userService.js(service file)
myapp.factory('myService',function($http){
var myService={
async : function(){
var promise= $http.get('http://jsonplaceholder.typicode.com/posts/1').then(function(response){
console.log(response);
return response;
});
return promise;
},
saveUser : function(user){
$http.post('http://jsonplaceholder.typicode.com/posts',user).success(
function(response,status,headers,config){
});
}
};
return myService;
});
restComponent.js(module file)
var myapp=angular
.module('demo',['ui.router'])
.config(function ($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home',{
url:'/home',
templateUrl:'Templates/home.html',
controller:'homeController'
})
.state('about', {
url:'/about',
templateUrl:'Templates/about.html',
controller:'aboutController'
})
.state('contact',{
url:'/contact',
templateUrl:'Templates/contact.html',
controller:'contactController'
});
});
home.html (view file)
<form ng-submit="mod.push();" ng-controller="homeController as mod">
Id:<br>
<input type="text" name="id" ng-model="mod.user.id"><br>
Model:<br>
<input type="text" name="model" ng-model="mod.user.model"><br>
Name:<br>
<input type="text" name="name" ng-model="mod.user.name"><br>
Color:<br>
<input type="text" name="color" ng-model="mod.user.color"><br>
Price:<br>
<input type="text" name="price" ng-model="mod.user.price"><br>
<br>
<input type="submit" >
</form>
<br>
<br>
<table>
<thead>
<th>UserId</th>
<th>Name</th>
<th>Country</th>
</thead>
<tbody>
<tr ng-repeat="employee in hello">
<td>{{employee.userId}}</td>
<td>{{employee.name}}</td>
<td>{{employee.country}}</td>
</tr>
</tbody>
</table>
index.html
<!doctype html>
<html lang="en" >
<head>
<meta charset="utf-8">
<title>RestApi</title>
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
<script src="bower_components/angular/angular.js"></script>
<script src="
https://cdnjs.cloudflare.com/ajax/libs/angular-ui- router/0.3.1/angular-ui-router.js
"></script>
<script src="rest-controller.component.js"></script>
<script src="Controllers/contact.js"></script>
<script src="Controllers/about.js"></script>
<script src="Controllers/home.js"></script>
<script src="Service/userService.js"></script>
</head>
<body ng-app="demo" >
<ol>
<li><a ui-sref="home">Home</a></li>
<li><a ui-sref="about">About</a></li>
<li><a ui-sref="contact">Contact</a></li>
</ol>
<div ui-view></div>
</body>
</html>
change that
you didnt declare your scope so its undefined that why better to declare it before using it
also removes that user array you did not need for that
var myapp = angular.module('demo').controller("homeController", function($scope,myService){
$scope.user = {}; // here you declare the user obkect
$scope.push = function(user){
myService.saveUser(user).then(function(response){
console.log("inserted");
});
}
})
and home html
you wanted to use scope but you used controller var
the view know the scope and all his objects so just write the var fun name and it will go to it directly
or you can do the same with controller by using this instead of scope and mod like you did
here you should send the user or you can do it in controller by sending the $scope.user
<form ng-submit="push(user);">
Id:<br>
<input type="text" name="id" ng-model="user.id"><br>
Model:<br>
<input type="text" name="model" ng-model="user.model"><br>
Name:<br>
<input type="text" name="name" ng-model="user.name"><br>
Color:<br>
<input type="text" name="color" ng-model="user.color"><br>
Price:<br>
<input type="text" name="price" ng-model="user.price"><br>
<br>
<input type="submit" >
</form>
and route
better to declare the controller on the view but you cant do them both so i chosed the view controller
var myapp=angular
.module('demo',['ui.router'])
.config(function ($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home',{
url:'/home',
templateUrl:'Templates/home.html'
})
.state('about', {
url:'/about',
templateUrl:'Templates/about.html'
})
.state('contact',{
url:'/contact',
templateUrl:'Templates/contact.html'
});
});
should work that way

How to set data to a service function in AngularJS ng-click

I am trying to persist information inside a service so that I can access the data across controllers. Here is what I tried :
HTML:
<div ng-app="myApp">
<div ng-controller="ControllerOne as one">
<h2>ControllerOne:</h2>
<table>
<tbody>
<tr ng-repeat="emp in EmployeeInfo">
<td>{{emp.name}}</td>
<td>{{emp.hireDate}}</td>
<td><a class="btn-sm btn-primary pull-right" ng-click="storeIds({{emp.idUser}})" >E-Verify</a></td>
</tr>
</tbody>
</table>
Change testService.loginName: <input type='text' ng-model='one.myService.UserId'/> </br></br>
myName: {{one.myService.UserId}}
</div>
<hr>
<div ng-controller="ControllerTwo as two">
<h2>ControllerTwo:</h2>
myName: {{two.myService.UserId}}
</div>
</div>
JS:
app.service('testService', function(){
this.UserId= uId;
});
app.controller('ControllerOne', function($scope, testService){
$scope.storeIds = function (userid) {
// HERE I want to call the testService and set the value.
}
this.myService = testService;
});
app.controller('ControllerTwo', function($scope, testService){
this.myService = testService;
});
have you tried looking into using $rootScope?
app.controller('ControllerOne', function($scope, rootScope, testService){
$scope.storeIds = function (userid) {
// HERE I want to call the testService and set the value.
}
$rootScope.myService = userid;
});
app.controller('ControllerTwo', function($scope, ,rootScope, testService){
//rootScope.myService will now equal whatever the userid was in the other controller.
//I skipped using the service
});

why Ng Repeat is not working if button invoked from a different form?

I have a html table that contains an ng repeat directive and two button.The first one will open a modal that contains a new form and let me create my user and then when i click save it will add it to the list.The second one is in the same original form and do the add a user.
What i did not understand why when i click on the first button which is in a different form i can not update the ng repeat however for the second one it's possible.
This is the code:
homepage.jsp
<body ng-app="myApp">
<div class="generic-container" ng-controller="UserController as ctrl">
<div id="createUserContent.jsp" ng-include="createUserContent"></div>
<table>
<tr>
<td>
<button type="button" class="btn btn-primary"
ng-click="ctrl.openCreateUser()">Create</button>
</td>
</tr>
</table>
<table class="table table-hover">
<thead>
<tr>
<th>ID.</th>
<th>Name</th>
<th>Address</th>
<th>Email</th>
<th width="20%"></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="u in ctrl.users">
<td><span ng-bind="u.ssoId"></span></td>
<td><span ng-bind="u.firstName"></span></td>
<td><span ng-bind="u.lastName"></span></td>
<td><span ng-bind="u.email"></span></td>
</tr>
</tbody>
</table>
</div>
</body>
user_controller.js
'use strict';
App.controller('UserController', function ($scope, UserService, $window, $log, $uibModalStack,
$uibModal, $rootScope) {
var self = this;
self.users = [];
self.fetchAllUsers = function () {
console.log('----------Start Printing users----------');
for (var i = 0; i < self.users.length; i++) {
console.log('FirstName ' + self.users[i].firstName);
}
};
/**
this function will not work
**/
self.saveUser = function (user) {
self.users.push(user);
self.fetchAllUsers();
$log.log("saving user");
$uibModalStack.dismissAll();
};
/**
this function works fine
**/
self.addNewRow = function () {
var specialUser = {
id : 12,
firstName : 'john',
lastName: 'travolta',
homeAddress : {location:'chicago'},
email : 'trav#email.com'
};
self.users.push(specialUser);
$log.log("saving specialUser");
};
self.openCreateUser = function () {
var modalInstance = $uibModal.open({
animation : true,
templateUrl : 'createUserContent',
controller : 'UserController',
resolve : {
items : function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
self.fetchAllUsers();
});
createUserContent.jsp
<form role="form" ng-controller="UserController as ctrl" >
<div class="form-group">
<label for="FirstName">FirstName</label> <input type="FirstName"
ng-model="ctrl.user.firstName" class="form-control"
id="FirstName" placeholder="Enter FirstName" /> <label
for="lastName">lastName</label> <input type="lastName"
class="form-control" id="lastName"
ng-model="ctrl.user.lastName" placeholder="Enter lastName" />
<label for="email">Email address</label> <input type="email"
ng-model="ctrl.user.email" class="form-control" id="email"
placeholder="Enter email" />
</div>
<div class="form-group">
<label for="homeAddressLocation">Home Address</label> <input class="form-control"
ng-model="ctrl.user.homeAddress.location" id="homeAddressLocation"
placeholder="homeAddressLocation" />
</div>
<div class="form-group">
<label for="SSOId">SSOId</label> <input class="form-control"
ng-model="ctrl.user.ssoId" id="SSOId" placeholder="SSOId" />
</div>
<button type="submit" class="btn btn-default"
ng-click="ctrl.saveUser(ctrl.user)">Save</button>
<button type="submit" class="btn btn-default">Cancel</button>
</form>
Because of your modal template can't access your UserController object and doesn't show error because you used in modal template same controller so reloaded as new Ctrl doesn't refer parent Ctrl.
However better to use different controller and pass parent controller object to modal controller and then modal body can use all parent object. so you should pass parent object to modal controller.
When you include createUserContent.jsp popup file in your main file then no need to use ng-controller="UserController as ctrl" in your modal template you used in modalInstance controller : 'Ctrl',
like:
var modalInstance = $uibModal.open({
templateUrl: 'createUserContent.jsp',
controller: 'ModalCtrl', // ModalCtrl for modal
controllerAs:'modal', // as modal so no need to use in modal template
size: 'lg',
resolve: {
items: function () {
return $scope.items;
},
parent: function(){ // pass self object as a parent to 'ModalCtrl'
return self;
}
}
and ModalCtrl like:
.controller('ModalCtrl', ['parent', function (parent) {
this.parent = parent;
}]);
here used ModalCtrl for modal as modal so you can access parent object like: modal.parent.user
template like:
<form role="form" >
<div class="form-group">
<label for="FirstName">FirstName</label> <input type="FirstName"
ng-model="modal.parent.user.firstName" class="form-control"
id="FirstName" placeholder="Enter FirstName" />
.....
....
<button type="submit" class="btn btn-default"
ng-click="modal.parent.saveUser(modal.parent.user)">Save</button>
<button type="submit" class="btn btn-default">Cancel</button>
</form>
More details Visit PLUNKER DEMO

Restangular does not PUT full object

I'm very new to it all so if I've made some massive oversights don't shout to hard.
I'm trying to update a table row using restangular. However it would seem like not all the object data is being set to the restapi. I have tested the restapi with POSTMAN so I know that works and I have also created new objects.
With google dev tools the PUT completes 200 OK but the Requested Payload only has the ID of the row. Actually if I attempt this on an existing row with data it clears all the data but the ID!
So here is what I have:
The HTML:
<div ng-controller="networksController">
<h1>{{title}}</h1>
<input type="text" ng-model="search" class="search-query" placeholder="Search">
<table class="table table-striped">
<thead>
<th>ID</th>
<th>Title</th>
<th>Reason</th>
<th>Actions</th>
<th>Requester</th>
<th>Verified</th>
<th></th>
</thead>
<tbody>
<tr ng-repeat="change in changes | filter:search">
<td>{{ change._id }}</td>
<td>
<div class="animate-show" ng-hide="editorEnabled">{{ change.title }}</div>
<div class="animate-show" ng-show="editorEnabled">
<input class="animate-input" type="text" ng-model="change.title" />
</div>
</td>
<td>
<div class="animate-show" ng-hide="editorEnabled">{{ change.reason }}</div>
<div class="animate-show" ng-show="editorEnabled">
<input class="animate-input" type="text" ng-model="change.reason" />
</div>
</td>
<td>
<div class="animate-show" ng-hide="editorEnabled">{{ change.actions }}</div>
<div class="animate-show" ng-show="editorEnabled">
<input class="animate-input " type="text" ng-model="change.actions" />
</div>
</td>
<td>
<div class="animate-show" ng-hide="editorEnabled">{{ change.requester }}</div>
<div class="animate-show" ng-show="editorEnabled">
<input class="animate-input" type="text" ng-model="change.requester" />
</div>
</td>
<td>
<div class="animate-show" ng-hide="editorEnabled">{{ change.verified }}</div>
<div class="animate-show" ng-show="editorEnabled">
<input class="animate-input" type="text" ng-model="change.verified" />
</div>
</td>
<td>
<input type="button" value="Edit" ng-hide="editorEnabled" ng-click="editorEnabled=!editorEnabled" />
<input type="button" value="Save" ng-show="editorEnabled" ng-click="editorEnabled=!editorEnabled; save(change)" />
<button ng-click="destroy(change)">Delete</button>
</td>
</tr>
</tbody>
</table>
The Main Controller:
var app = angular.module('richApp', ['ngResource', 'ngAnimate', 'restangular', 'xeditable'])
.config(function(RestangularProvider) {
RestangularProvider.setBaseUrl('api/');
});
The Page Controller:
app.controller('networksController', ['$scope', '$resource', 'Restangular', function($scope, $resource, Restangular) {
$scope.title = 'Network Control APP';
var baseChanges = Restangular.all('changes');
baseChanges.getList().then(function(changes) {
$scope.allChanges = changes;
});
$scope.changes = Restangular.all('changes').getList().$object;
$scope.destroy = function(change) {
Restangular.one("changes", change._id).remove();
};
$scope.save = function(change) {
Restangular.one("changes", change._id).put();
};
}]);
Ok so after 3 days of hunting high and low I finally find the answer. Mongo and restangular use different ID Keys. mongo uses _id whereas restangular uses id.
In order to correct this I needed to add the following
var app = angular.module('richApp', ['ngResource', 'ngAnimate', 'restangular', 'xeditable'])
.config(function(RestangularProvider) {
RestangularProvider.setBaseUrl('api/');
RestangularProvider.setRestangularFields({ //Added this
id: "_id" //Added this
}); //Added this
});
It's fair to say I also modified the following:
$scope.save = function(change) {
Restangular.one("changes", change._id).get().then(function(data) {
$scope.data = data;
});
var original = change;
$scope.data = Restangular.copy(original);
$scope.data.save();
};
I think you should use
$scope.save = function(change) {
change.put();
};

Categories

Resources