Angularjs: View not updating list after POST - javascript

I am currently working on a small angularjs app which is basically a user profile management app.
The problem i am having is with adding users dynamically. When i enter the user data, it successfully POST's to my local server i have setup, BUT i have to refresh the page to see the new user in the users list
I obviously dont want to have to refresh.
-Yes i've tried $scope.apply() after running the POST function
Something i am noticing with Angular Batarang (Debugging tool), is that the scope is updating fine, but there is a blank spot or 'null' value where the new user should be.
Here are the Controllers:
UsersApp.controller('UserListController', [ '$scope', 'userService', function($scope, userService) {
$scope.usersList = userService.usersList;
$scope.users = userService.users;
$scope.user = userService.user;
}]);
UsersApp.controller('AddUserController', function($scope, $window, dataResources, userService) {
$scope.addNew = function addNew(newUser) {
$scope.usersList = userService.usersList;
var firstName = newUser.firstName;
var lastName = newUser.lastName;
var phone = newUser.phone;
var email = newUser.email;
$scope.newUserData = {
firstName , lastName, phone , email
}
new dataResources.create($scope.newUserData);
$scope.usersList.push(dataResources);
$scope.$apply();
};
And Here are my views:
Add User:
<script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
<script src="js/minimize.js"></script>
<div ng-controller="AddUserController">
<div class="userInfo" id="usernameDiv">
<h2 id="username">User<img id="showhide" src="images/plus.png" style="position:absolute; padding-left:15px; width:31px; color:white;"></h2>
</div>
<div class="userInfo">
<div id="listInfo">
<form ng-controller="AddUserController">
<input type="text" placeholder= "First Name" ng-model="newUser.firstName"></input>
<input type="text" placeholder= "Last Name" ng-model="newUser.lastName"></input>
<input type="text" placeholder= "Phone Number" ng-model="newUser.phone"></input>
<input type="text" placeholder= "Email" ng-model="newUser.email"></input>
<button type="submit" ng-click="addNew(newUser)">Add User</button>
</form>
</div>
</div>
Users List:
<!DOCTYPE html>
<html>
<head></head>
<body id="">
<div ng-controller="UserListController">
<div class="userInfo">
<h2>List of Users</h2>
<div id="listInfo">
<ul style="list-style-type: none;">
<li ng-repeat="user in usersList">
<!--<p class="userData">ID: {{ user }}</p> -->
<p class="userData"><a style="cursor:pointer;" ui-sref="UserProfile">{{ user.firstName }}</a></p>
</li>
</ul>
</div>
</div>
Factory and Service:
UsersApp.factory('dataResources', [ '$resource', function($resource) {
return $resource('http://localhost:24149/users/:id', {}, {
query: {method:'GET', params:{idnum: '#id'}, isArray:true},
create: {method:'POST', headers: { 'Content-Type': 'application/json' }},
update: {method:'PUT', params:{idnum: '#id'}},
remove: {method:'DELETE', params:{idnum:'#id'}, isArray:true}
});
}]);
UsersApp.service('userService', function(dataResources) {
return {
usersList: dataResources.query()
}
});

I'm not sure if I follow exactly, but I believe you need to deal with a promise from your POST and then push the result. e.g.,
dataResources.create($scope.newUserData).$promise.then(function(data) {
$scope.usersList.push(data);
});
Your service will return a promise and then when the POST is complete your service should return the new user and you just add it to your current list.

See $resource documentation:
non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
According to the doc your code should look like this:
dataResources.create($scope.newUserData,
function(data) {
$scope.usersList.push(data);
}
);
controller: you don't need to make a new userdata object, you can just use newUser
UsersApp.controller('AddUserController', function($scope, $window, dataResources, userService) {
$scope.usersList = userService.usersList;
$scope.addNew = function addNew(newUser) {
dataResources.create($scope.newUser,
function(data) {
$scope.usersList.push(data);
}
);
};
};

Same idea for angular2 using observables.
public posts: any;
onPost(input) {
this.dataService.jsonserverPost(input)
.subscribe(
(data: any) => {
this.posts.push(data);
}
);
}

Related

How do I pass array information using a factory in Javascript?

Using a factory, I want to get information from one page (text fields and a submit button), put it in an array, and read from that array to post it into a different page. Here is a snippet of my code.
app.factory("service", function(){
var serv = {};
serv.arr = [];
serv.add = (title, name, post, tag) => serv.arr.push({
"title" : title, "name" : name, "post" : post, "tag" : tag
});
return serv;
});
app.controller("createCtrl", ["$scope", "service", function($scope, service)
{
display = () => service.add($scope.title, $scope.name, $scope.post,
$scope.tag);
console.log(service.arr);
}]);
app.controller("newsCtrl", ["$scope", "service", function($scope, service){
$scope.newsPage = "News";
$scope.array = service.arr;
}]);
I know I'm probably way off but at this stage I can't even tell if any information is being added to the array.
Try below code for set & get data from factory.
Click on SAVE DATA & then GET DATA buttons to see the actions
(function(ng, app){
app = angular.module('app', [])
app.factory("service", function(){
var serv = {};
var arr = [];
return {
add : function (title, name, post, tag) {
arr.push({
"title" : title, "name" : name, "post" : post, "tag" : tag
});
},
get : function (firstname) {
return arr[0];
}
}
});
app.controller("createCtrl", ["$scope", "service", function($scope, service)
{
$scope.display = function(){
service.add($scope.title, $scope.name, $scope.post, $scope.tag);
};
}]);
app.controller("newsCtrl", ["$scope", "service", function($scope, service){
$scope.newsPage = "News";
$scope.getData = function(){
$scope.array = service.get();
};
}]);
}(angular));
input {
margin: 5px;
}
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-controller="createCtrl as main">
<h1>create Ctrl</h1>
<input ng-model="title" placeholder="title" /><br/>
<input ng-model="name" placeholder="name" /><br/>
<input ng-model="post" placeholder="post" /><br/>
<input ng-model="tag" placeholder="tag" /><br/>
<button ng-click="display()"> SAVE DATA </button>
</div>
<br/> <hr/>
<div ng-controller="newsCtrl">
<h2>news Ctrl </h2>
<button ng-click="getData()"> GET DATA </button>
<p> title : {{array.title}} </p>
<p> name : {{array.name}} </p>
<p> post : {{array.post}} </p>
<p> tag : {{array.tag}} </p>
</div>
</body>
</html>

How to check in AngularsJS a unique Database value filled in a form

I have created an application managing contacts. The user can add a contact. After filling the name, I would like to check if the value already exists in the DB.
Can you please help for doing that?
I have created a new field username and I created a directive but I don't know if this way is the best solution. The query is correctly executed. But I improve some difficulties for displaying the results "username exists already" (during the loading it's correctly displayed "checking.....").
Here the file app.js (with the module and the controler "ctrlContacts"):
var app=angular.module('ContactsApp', ['ngRoute', 'ui.bootstrap', 'ngDialog']);
// register the interceptor as a service
app.factory('HttpInterceptor', ['$q', '$rootScope', function($q, $rootScope) {
return {
// On request success
request : function(config) {
// Return the config or wrap it in a promise if blank.
return config || $q.when(config);
},
// On request failure
requestError : function(rejection) {
//console.log(rejection); // Contains the data about the error on the request.
// Return the promise rejection.
return $q.reject(rejection);
},
// On response success
response : function(response) {
//console.log(response); // Contains the data from the response.
// Return the response or promise.
return response || $q.when(response);
},
// On response failure
responseError : function(rejection) {
//console.log(rejection); // Contains the data about the error.
//Check whether the intercept param is set in the config array.
//If the intercept param is missing or set to true, we display a modal containing the error
if (typeof rejection.config.intercept === 'undefined' || rejection.config.intercept)
{
//emitting an event to draw a modal using angular bootstrap
$rootScope.$emit('errorModal', rejection.data);
}
// Return the promise rejection.
return $q.reject(rejection);
}
};
}]);
// MY DIRECTIVE FOR CHECKING IF THE USERNAME IS ALREADY USED
app.directive('usernameAvailable', function($timeout, $q, $http, ContactService) {
return {
restrict: 'AE',
require: 'ngModel',
link: function(scope, elm, attr, ngModel) {
ngModel.$asyncValidators.usernameExists = function() {
return ContactService.searchContactByName('ADAM').success(function(contact){
$timeout(function(){
ngModel.$setValidity('usernameExists', contact);
ngModel.$setValidity('unique', false);
scope.contacts = contact;
alert(contact.length);
}, 1000);
});
};
}
}
});
app.controller('ctrlAddContacts', function ($scope, ContactService){
$scope.title="Add a contact";
ContactService.getCountry().success(function(countries){
$scope.countries = countries;
});
ContactService.loadCategory('undefined',0).success(function(categories){
$scope.categories = categories;
});
$scope.Category = function (contactType) {
if (contactType){
ContactService.loadCategory(contactType,0).success(function(categories){
$scope.categories = categories;
});
}
}
$scope.submitForm = function(contact){
if($scope.ContactForm.$valid){
ContactService.addNewPerson(contact).success(function(Person){
$scope.ContactForm.$setPristine();
$scope.contact= Person;
var personID = Person[0]["ID"];
window.location="#/view-contacts/" + personID;
});
}
}
});
the file for the factories: "appServices.js":
app.factory('ContactService', function($http){
var factory={};
factory.searchContactByName=function(string){
if (string){
chaine='http://myapp/contacts.cfc?method=searchContactByName&contactName=' + string;
}else{
chaine='';
}
//alert(chaine);
return $http.get(chaine);
};
return factory;
})
the file for my view "manageContact.html":
<h3>{{title}}</h3>
<div class="panel panel-default">
<div class="panel-heading">
<div class="panel-title">Person Sheet</div>
</div>
<div class="panel-body">
<form name="ContactForm" class="form-horizontal" role="form" novalidate ng-submit="submitForm(contact)">
<!--------------------- USERNAME FIELD AND CHECK IF IT EXISTS ------------------START-->
<div>
<input type="text"
name="username"
ng-model="username"
username-available
required
ng-model-options="{ updateOn: 'blur' }">
<div ng-if="ContactForm.$pending.usernameExists">checking....</div>
<div ng-if="ContactForm.$error.usernameExists">username exists already</div>
</div>
<!---------------------- USERNAME FIELD AND CHECK IF IT EXISTS --------------------END-->
<div class="form-group">
<label for="txtLastName" class="col-sm-2 control-label">Last Name *</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="txtLastName" maxlength="100" placeholder="Enter Last Name" required ng-model="contact.LASTNAME">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<input type="submit" class="btn btn-primary" value="Submit" ng-disabled="ContactForm.$invalid">
Cancel
</div>
</div>
</form>
</div>
</div>
Thank you in advance for your help.
Regards,
it should be
<div ng-if="ContactForm.$pending.usernameExists">checking....</div>
<div ng-if="ContactForm.username.$error.unique">username exists already</div>
Use ng-show and ng-hide instead of ng-if
<div ng-show="ContactForm.$pending.usernameExists">checking....</div>
<div ng-show="ContactForm.$error.usernameExists">username exists already</div>

put facebook login data into textfields with angualrjs

I'm implementing facebook login and its working alright with angular.but the problem is when i get the data from facebook i'm unable to put in a textfield. when i put it in an alert its able to give me the data but can't put it in a textfield.
<div ng-controller="facebook_login">
<p align="center"><button class="icon icon-left ion-social-facebook button button-positive button-small" ng-click="fbLogin()">Sign Up with Facebook</button></p>
<div class="list">
<div class="item">
<label class="item item-input item-stacked-label">
<span class="input-label">Fashion Line</span>
<input type="text" ng-model="email" ng-value="{{data.email}}" />
<div>
JS
.controller('facebook_login',['$scope', '$ionicModal', '$timeout', 'ngFB', function($scope, $ionicModal, $timeout, ngFB) {
$scope.fbLogin = function () {
ngFB.login({scope: 'email,public_profile,publish_actions'}).then(
function (response) {
if (response.status === 'connected') {
//alert('Facebook login succeeded, got access token: ' + response.authResponse.accessToken);
//$scope.closeLogin();
ngFB.api({
path: '/me',
params: {fields: 'first_name,last_name,gender,email,picture'}
}).then(
function (data) {
$scope.facebook = data;
alert(data.email)
$scope.email = $scope.data.email;
document.getElementById("email").innerHTML = data.email;
});
} else {
alert('Facebook login failed');
}
});
};
}])
Seems like you never defined $scope.data but you're trying to use it. Did you mean $scope.facebook.email instead?

AngularJS Data inserted successfully but it display Error code

I used Spring framework as a back-end and angular as a front end. When I try to insert data from the angualrJs value is inserted into database but display error code. please suggest me what is the wrong in this code.
var app = angular.module("categoryApp", []);
app.controller('submitCategory', [ '$scope', '$http',
function($scope, $http) {
$scope.submitClick = function() {
var dataObj = {
name : $scope.name
};
var result = $http.post("/tutorials/category", dataObj);
result.success(function(data, status, headers, config) {
alert("success");
$scope.message = data;
});
result.error(function(data, status, headers, config) {
alert("failure message: " + JSON.stringify({
data : data
}));
});
$scope.name = '';
}
}
]);
And my html is
<body ng-app="categoryApp">
<section class="panel" ng-controller="submitCategory">
<header class="panel-heading"> Basic Forms </header>
<div class="panel-body">
<form role="form" method="post" ng-submit="submitClick()">
<div class="form-group">
<label for="category">Category</label> <input type="text"
class="form-control" id="exampleInputEmail1" name="name"
placeholder="Category" ng-model="name">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</section>
</body>
And my controller method is
#RequestMapping(value = "/category", method = RequestMethod.POST)
public ResponseEntity<String> postCategory(#RequestBody Category category,
Model model) {
categoryService.save(category);
return new ResponseEntity<String>("success", HttpStatus.OK);
}
The issue is caused by ResponseEntity<String> .Your code java should be like this:
#RequestMapping(value = "/category", method = RequestMethod.POST)
public ResponseEntity<String> postCategory(#RequestBody Category category,
Model model) {
categoryService.save(category);
return new ResponseEntity<String>("success", HttpStatus.OK); }

How to send data from input to service?

I have a problem with a sending data form input to the service.
For example I have an input:
<input type="text" class="form-control" placeholder="City name...">
<span class="input-group-btn">
<button class="btn btn-default" type="button">Go!</button>
</span>
And a service which is geting data for rest api:
app.factory('forecast', ['$http', function($http) {
return $http.get('http://api.openweathermap.org/data/2.5/forecast/city?q=Warsaw&units=metric&mo')
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}]);
How can I send the city name from the input after clicking button "Go" to construct my own api link ? And then display those data in view ?
I mean something like this http://api.openweathermap.org/data/2.5/forecast/city?q=VALUE_FROM_THE_INPUT&units=metric&mo
You should assign your input an ng-model directive, like this:
<input type="text" class="form-control" placeholder="City name..." ng-model="city.name">
Assign your button an ng-click directive, like this:
<button class="btn btn-default" type="button" ng-click="getForecast(city)">Go!</button>
Finally, add getForecast function to your controller, like this:
$scope.getForecast = function (city) {
forecast.getForecast($scope.city).then(function (data) {
// do something with the response
}, function (err) {
// do something about the error
});
}
For this to work you should change your service to something like this:
app.factory('forecast', ['$http', function($http) {
return {
getForcast: function (city) {
$http.get('http://api.openweathermap.org/data/2.5/forecast/city?q=' + city.name + '&units=metric&mo');
}
};
}]);
your HTML :
<input type="text" class="form-control" placeholder="City name..." ng-model="city">
<span class="input-group-btn">
<button class="btn btn-default" type="button" ng-click="go()">Go!</button>
</span>
your Factory :
app.factory('forecast', ['$http', function($http) {
this.sendAPIRequest = function(city){
$http.get('http://api.openweathermap.org/data/2.5/forecast/city?q='+city+'&units=metric&mo')
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
};
return this;
}]);
your Controller :
app.controller('myCtrl', ['$scope', 'forecast', function ($scope, forecast) {
$scope.go = function(){
$scope.data = forecast.sendAPIRequest($scope.city);
};
}])
You seem to be asking a few questions, but lets just start with the "GO" to link using input. since you're using an angular factory you may want to use a controller or something:
HTML:
<div ng-controller="formCtrl">
<input type="text" class="form-control" placeholder="City name..." ng-model="city">
<span class="input-group-btn">
<button class="btn btn-default" type="button" ng-click="goToUrl(city)">Go!</button>
</span>
</div>
now you want to pass that city to the url name?
app.factory('forecast', ['$http', function($http) {
var forecastFactory = {};
forcastFactory.customUrl = function(city){
$http.get('http://api.openweathermap.org/data/2.5/forecast/city?' + city +'q=Warsaw&units=metric&mo')
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}
return forecastFactory;
}]);
app.controller('formCtrl', ['forecast', function(Forecast){
$scope.goToUrl = function(name){
var data = Forecast.customUrl(name);
}
}]);

Categories