Angular updating and clearing factory variables - angularjs

I'm creating a single page app in which a user searches for a term, the result gets saved in a variable, and a new page is routed that displays the result. I have this functionality working, however I want the variable to be cleared when the user returns to the previous page and most importantly when the user logs out. What's the proper way to do this? I want the factory to save things for certain pages that I want, and clear them for certain pages I don't want like "home" or "logout".
Factory:
angular.module('firstApp')
.factory('fact', function () {
var service = {};
var _information = 'Default Info';
service.setInformation = function(info){
_information = info;
}
service.getInformation = function(){
return _information;
}
return service;
});
Controller:
angular.module('firstApp')
.controller('InformationCtrl', function($scope, $http, $location, fact) {
$scope.message = 'Hello';
$scope.result = fact.getInformation();
$scope.sub = function(form) {
console.log($scope.name);
$scope.submitted = true;
$http.get('/wiki', {
params: {
name: $scope.name,
}
}).success(function(result) {
console.log("success!");
$scope.result = result;
fact.setInformation(result);
$location.path('/informationdisplay');
});;
}
});
Routes
angular.module('firstApp')
.config(function ($routeProvider) {
$routeProvider
.when('/information', {
templateUrl: 'app/information/input.html',
controller: 'InformationCtrl',
authenticate : true
})
.when('/informationdisplay', {
templateUrl: 'app/information/results.html',
controller: 'InformationCtrl',
authenticate : true
});
});
input.html
<div class="row">
<div class="col-md-6 col-md-offset-3 text-center">
<p>{{result}}</p>
<form class="form" name="form" ng-submit="sub(form)" novalidate>
<input type="text" name="name" placeholder="Name" class="form-control" ng-model="name">
</br>
<button class="btn btn-success" type="submit" class="btn btn-info">Check</button>
</div>
</div>
results.html
<div ng-include="'components/navbar/navbar.html'"></div>
<div class="row">
<div class="col-sm-4 col-sm-offset-4">
<h2>Information Results</h2>
<p>{{result}}</p>
</div>
</div>
</div>

If you want it to wipe the value when they change routes (which logout should change routes also, I assume), you can watch the $routeChangeStart event and have it wipe the value whenever it occurs. You put that function in the module.run block:
app.run(function ($rootScope, fact) {
$rootScope.$on("$routeChangeStart",function(event, next, current){
fact.setInformation(null);
});
});

Related

$scope not displaying data

The $scope data is not displaying on the page.
I have 2 views that are using the same controller.
I have this view, and I'm clicking the edit issue button
<div class="container" data-ng-init="adminInit()">
<div class="row">
<div class="col-lg-12">
<div class="page-header text-center">
<h1>Issues Admin</h1>
<button type="button" class="btn btn-primary" ui-sref="add-issue">
Add Issue
</button>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h3>Current Issues</h3>
<ul ng-repeat="issue in issues">
<li>
<strong>{{issue.title}}</strong> - Current Status:
<strong>{{issue.status}}</strong>
<div ng-hide="true" class="btn btn-xs btn-primary glyphicon glyphicon-pencil" ng-click="editIssue(issue._id)"></div>
<div class="btn btn-xs btn-primary glyphicon glyphicon-pencil" ng-click="editIssue(issue._id)"></div>
<div class="btn btn-xs btn-danger glyphicon glyphicon-remove" ng-click="deleteIssue(issue._id)"></div>
</li>
<ul>
<li>{{issue.description}}</li>
<li>Issue Logged at: {{issue.timestamp | date:'MM/dd/yyyy # h:mma'}}</li>
</ul>
</ul>
</div>
</div>
</div>
And this in my controller
$scope.editIssue = function(id) {
$state.go('edit-issue');
$http.get(Configuration.API + 'api/issue/' + id)
.then(function successCallback(response) {
$scope.issueToEdit = response.data;
console.log($scope.issueToEdit);
});
};
then the edit-issue view
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="page-header text-center">
<h1>Edit Issue</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<form name="frm" ng-submit="updateIssue()">
<div class="form-group">
<label for="editIssueTitle">Issue Title</label>
<input type="text" name="editIssueTitle" id="editIssueTitle" class="form-control" ng-model="issueToEdit.title" required/>
</div>
<div class="form-group">
<label for="editIssueDesc">Issue Description</label>
<textarea name="editIssueDesc" id="editIssueDesc" class="form-control" cols="60" rows="16" ng-model="issueToEdit.description" required></textarea>
</div>
<div class="form-group">
<label for="editIssueStatus">Issue Status</label>
<select name="editIssueStatus" id="editIssueStatus" class="form-control" ng-model="issueToEdit.status" required>
<option value="Identified">Identified</option>
<option value="Investigating">Investigating</option>
<option value="Monitoring">Monitoring</option>
<option value="Resolved">Resolved</option>
</select>
</div>
<button class="btn btn-default" ng-disabled="frm.$invalid">Go</button>
</form>
</div>
</div>
</div>
But the issueToEdit data is never displayed
The console.log line displays the right data
{
"_id": "58135b6e3987b8a90c4fc15b"
"title": "Test"
"description": "Testset"
"timestamp": "2016-10-28T14:06:38.284Z"
"status": "Monitoring"
"__v": 0
}
Any idea why this is happening?
EDIT: Let me clarify a little, when I land on the edit-issue page, I want the issueToEdit data to displayed in the form so that I can then update the info and then save it.
EDIT2: Here is my full controller and app.js
app.controller('issuesController', ['$scope', '$http', '$state', '$interval', 'auth', 'Configuration', function($scope, $http, $state, $interval, auth, Configuration) {
$scope.isLoggedIn = auth.isLoggedIn;
$scope.getIssues = function() {
console.log('retrieving issues');
$http.get(Configuration.API + 'api/issue')
.success(function(data) {
$scope.issues = data;
})
.error(function(data) {
console.log('Error: ' + data);
});
};
$scope.addIssue = function() {
var nIssue = {
'title': $scope.newissue.title,
'description': $scope.newissue.description,
'timestamp': new Date(),
'status': $scope.newissue.status
}
$http.post(Configuration.API + 'api/issue', nIssue)
.success(function(data) {
$state.go('admin');
})
.error(function(data) {
console.log('Error: ' + data);
});
};
$scope.editIssue = function(id) {
$state.go('edit-issue');
$http.get(Configuration.API + 'api/issue/' + id)
.then(function successCallback(response) {
$scope.issueToEdit = response.data;
console.log($scope.issueToEdit);
});
};
$scope.updateIssue = function() {
//ToDo add this logic
};
$scope.deleteIssue = function(id) {
$http.delete(Configuration.API + 'api/issue/' + id)
.success(function(data) {
$scope.issues = data;
})
.error(function(data) {
console.log('Error: ' + data);
});
};
$scope.adminInit = function() {
$scope.getIssues();
$interval($scope.getIssues, 60000);
};
$scope.issueInit = function() {
$scope.getIssues();
$interval($scope.getIssues, 60000);
$(".devInfo").text(navigator.userAgent);
$(".flashVersion").text(FlashDetect.raw);
};
}]);
app.js
var app = angular.module('supportWebsite', ['ui.router']);
app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise('/articles');
$stateProvider
.state('home', {
url: '/',
templateUrl: '/pages/issues/index.html',
controller: 'issuesController'
})
.state('admin', {
url: '/admin',
templateUrl: '/pages/issues/admin/index.html',
controller: 'issuesController',
onEnter: ['$state', 'auth', function($state, auth) {
if (!auth.isLoggedIn()) {
$state.go('login');
}
}]
})
.state('add-issue', {
url: '/admin/add-issue',
templateUrl: '/pages/issues/admin/add.html',
controller: 'issuesController',
onEnter: ['$state', 'auth', function($state, auth) {
if (!auth.isLoggedIn()) {
$state.go('login');
}
}]
})
.state('edit-issue', {
url: '/admin/edit-issue',
templateUrl: '/pages/issues/admin/edit.html',
controller: 'issuesController',
onEnter: ['$state', 'auth', function($state, auth) {
if (!auth.isLoggedIn()) {
$state.go('login');
}
}]
});
$locationProvider.html5Mode(true);
}]);
Your method tells the $state service to go to another state. That will replace the view by the view associated with the new state, create a new $scope, and a new controller instance using this new $scope.
So whatever you put in the $scope of the current controller is irrelevant and useless: the other state uses another $scope and another controller.
You need to pass the ID of the issue to edit as a parameter of the new state. And the controller of this new state (or one of its resolve functions) should use that ID to get the issue to edit.
If you want to stay on the same view, using the same controller and the same scope, then you shouldn't navigate to another state.

Passing data from one page to another in angular js

How do I pass data from one page to another in angular js?
I have heard about using something as services but I am not sure how to use it!
Given below is the functionality I want to execute!
On page 1:
<div class="container" ng-controller="mycontrl">
<label for="singleSelect"> Select Date </label><br>
<select nAMe="singleSelect" ng-model="dateSelect">
<option value="2/01/2015">2nd Jan</option>
<option value="3/01/2015">3rd Jan</option>
</select>
<br>
Selected date = {{dateSelect}}
<br/><br/><br/>
<label for="singleSelect"> Select time </label><br>
<select nAMe="singleSelect" ng-model="timeSelect">
<option value="9/10">9AM-10AM</option>
<option value="10/11">10AM-11AM</option>
<option value="11/12">11AM-12PM</option>
<option value="12/13">12PM-1PM</option>
<option value="13/14">1PM-2PM</option>
</select>
<button ng-click="check()">Check!</button>
<br>
Selected Time = {{timeSelect}}
<br/><br/>
User selects time and date and that is used to make call to the db and results are stored in a variable array!
Page 1 controller:
var config= {
params: {
time: times,
date:dates
}
};
$http.get('/era',config).success(function(response) {
console.log("I got the data I requested");
$scope.therapist_list = response;
});
Now how do I send this variable $scope.therapist_list which is an array to next page which will be having a different controller and also if services is use how do define it in my application.js file
application.js:
var firstpage=angular.module('firstpage', []);
var secondpage=angular.module('secondpage', []);
To save the data that you want to transfer to another $scope or saved during the routing, you can use the services (Service). Since the service is a singleton, you can use it to store and share data.
Look at the example of jsfiddle.
var myApp = angular.module("myApp", []);
myApp.controller("ExampleOneController", function($scope, NewsService) {
$scope.news = NewsService.news;
});
myApp.controller("ExampleTwoController", function($scope,NewsService) {
$scope.news = NewsService.news;
});
myApp.service("NewsService", function() {
return {
news: [{theme:"This is one new"}, {theme:"This is two new"}, {theme:"This is three new"}]
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="ExampleOneController">
<h2>
ExampleOneController
</h2>
<div ng-repeat="n in news">
<textarea ng-model="n.theme"></textarea>
</div>
</div>
<div ng-controller="ExampleTwoController">
<h2>
ExampleTwoController
</h2>
<div ng-repeat="n in news">
<div>{{n.theme}}</div>
</div>
</div>
</body>
UPDATED
Showing using variable in different controller jsfiddle.
var myApp = angular.module("myApp", []);
myApp.controller("ExampleOneController", function($scope, NewsService) {
$scope.newVar = {
val: ""
};
NewsService.newVar = $scope.newVar;
$scope.news = NewsService.news;
});
myApp.controller("ExampleTwoController", function($scope, NewsService) {
$scope.anotherVar = NewsService.newVar;
$scope.news = NewsService.news;
});
myApp.service("NewsService", function() {
return {
news: [{
theme: "This is one new"
}, {
theme: "This is two new"
}, {
theme: "This is three new"
}]
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="ExampleOneController">
<h2>
ExampleOneController
</h2>
<div ng-repeat="n in news">
<textarea ng-model="n.theme"></textarea>
</div>
<input ng-model="newVar.val">
</div>
<div ng-controller="ExampleTwoController">
<h2>
ExampleTwoController
</h2>
<div ng-repeat="n in news">
<div>{{n.theme}}</div>
</div>
<pre>newVar from ExampleOneController {{anotherVar.val}}</pre>
</div>
</body>
OK,
you write a another module ewith factory service e.g.
angular
.module('dataApp')
.factory('dataService', factory);
factory.$inject = ['$http', '$rootScope', '$q', '$log'];
function factory($http, $rootScope,$q,$log) {
var service = {
list: getList
};
service.therapist_list = null;
return service;
function getList() {
var config= {
params: {
time: times,
date:dates
}
};
$http.get('/era',config).success(function(response) {
console.log("I got the data I requested");
$scope.therapist_list = response;
});
$log.debug("get Students service");
$http.get('/era',config).then(function successCallback(response) {
service.therapist_list = response.data;
$log.debug(response.data);
}, function errorCallback(response) {
$log.debug("error" + response);
});
}
}
Add this module as dependencies to your both page apps like
var firstpage=angular.module('firstpage', [dataApp]);
var secondpage=angular.module('secondpage', [dataApp]);
and then in your controller consume that service
.controller('homeController', ['$scope', 'dataService', function ($scope, dataService) {
}]);

Post angularjs form to nodejs Express ( Bad request)

im new in angularJs, im trying to make a basic login with angularJS and nodejs ( server side), i dont care about security for now im just trying to learn how to post. so i made a login form and a controller with angular :
My Login Form :
<div class="col-md-4">
<h1>Login</h2>
<form class="form" >
<div class="form-group">
<label>Username</label>
<input type="email" class="form-control" ng-model="login.mail" required>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" ng-model="login.password" required>
</div>
<div>
<button type="text" class="btn btn-default" ng-click="login()">Login</button>
</div>
</form>
</div>
then my router & controller Angularjs :
'use strict';
angular.module('login', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/login', {
templateUrl: 'views/login.html',
controller: 'loginCtrl'
});
}])
.controller('loginCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.login = function() {
$http.post('/api/users/login', $scope.login).success(function (response) {
console.log(response);
// refresh();
});
};
}]);
and Server side i have that :
router.post('/login/', function(req, res) {
// here "/login/" means "/users/login" ( in index of controllers)
console.log(req.body.mail);
var usermail = req.body.mail;
var pass = req.body.password;
console.log(usermail + pass);
User.find({mail: usermail}, function(err, user) {
if (err) {
res.send(err);
console.log("ça marche pas")
} else {
res.json( user );
console.log(user);
}
})
});
server side : it works ( when i use DHC chrome extension to Post) but when im using angularjs view i got that error :
POST http://localhost:3000/api/users/login 400 (Bad Request)
Please help me to solve that, i think i missed something. Thank you in advance.
I think you are sending your login function as in below line:
$http.post('/api/users/login', $scope.login)
You probably want to pass a parameter in your login function that can be sent to server as below:
$scope.login = function(loginData) {
$http.post('/api/users/login', loginData).success(function (response)
Update
You are assigning your form values to $scope.login. If you would create a separate variable for it, for example loginForm, you can send this as valid JSON to your API:
<div class="col-md-4">
<h1>Login</h2>
<form class="form" >
<div class="form-group">
<label>Username</label>
<input type="email" class="form-control" ng-model="loginForm.mail" required>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" ng-model="loginData.password" required>
</div>
<div>
<button type="text" class="btn btn-default" ng-click="login(loginData)">Login</button>
</div>
</form>
</div>
And .js:
.controller('loginCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.loginForm = {
mail: '',
password: ''
};
$scope.login = function(loginData) {
// Check what this prints out:
console.log(loginData);
$http.post('/api/users/login', loginData).success(function (response) {
console.log(response);
// refresh();
});
};
}]);

Angularjs scope not working

I am using basic angular.js concept to show and hide a div. For some reasons I am unable to make it work.
While Uploading a file I am showing a div 'myFormSpinner' on the basis of registerStart value. I am creating a phone gap app.
Could someone please help me in finding the issue. Apart from showing/hiding div everything works fine. Below is the code snippet:
<div class="row" ng-controller="RegisterCtrl">
<div id="myFormSpinner" ng-show="registerStart">
<img src="img/ajax-loader.gif">
</div>
<div class="col-md-8">
<form class="ng-pristine ng-invalid ng-invalid-required" style="margin-top:5%;">
<div class="col-md-6">
<input class="form-control " type="text" ng-model="registerData.Email" id="Email" name="Email" required placeholder="Email">
</div>
<div class="col-md-offset-1 col-md-10 ">
<input type="submit" ng-click="register()" value="Register" class="btn btn-default btn-primary">
</div>
</form>
</div>
event.controller('RegisterCtrl', ['$scope', '$state', '$q', '$http', 'eventService', 'authService', '$stateParams', '$rootScope', 'tokenService', 'imageService', 'spinnerService', 'appBackgroundService',
function ($scope, $state, $q, $http, eventService, authService, $stateParams, $rootScope, tokenService, imageService, spinnerService, appBackgroundService) {
var userNumber = 0;
$scope.mediaUploadStart = false;
$scope.eventId = $state.params.id;
$scope.register = function () {
$scope.registerStart = true;
console.log('scope.Pic=' + $scope.pic);
if ($scope.registerData.Email) {
spinnerService.show('myFormSpinner');
$scope.mediaUploadStart = true;
var paramOptions = {
eventId: $state.params.id,
email: $scope.registerData.Email,
fb: {},
number: userNumber,
provider: "Form"
};
uploadPicAndData(paramOptions).then(function (result) {
var data = JSON.parse(result);
$scope.registerStart = false;
appBackgroundService.disableBackgroundMode();
},
function (error) {
spinnerService.hide('myFormSpinner');
$scope.registerStart = false;
appBackgroundService.disableBackgroundMode();
});
$scope.mediaUploadStart = false;
spinnerService.hide('myFormSpinner');
}
};
}])
You are setting the $scope element in an async mode.
the digest cycle is not able to determine that a change has been made to the scope element in an async mode.
You should use $apply to activate the digest cycle.
$scope.$apply(function () { $scope.registerStart = false; });
Read more about $apply here: http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

Why won't my view template bind to a scope variable with AngularJS?

My view is:
<div class="container" ng-controller="MyController">
<div class="row">
<div class="col-md-8">
<textarea class="form-control" rows="10" ng-model="myWords" ng-change="parseLanguage()"></textarea>
</div>
<div class="col-md-4" ng-show="sourceLanguage !== null">
Language: {{ sourceLanguage }}
</div>
</div>
</div>
My controller is:
webApp.controller('MyController', [
'$scope', '$rootScope', 'TranslateService', function($scope, $rootScope, CodeService) {
$scope.init = function() {
return $scope.sourceLanguage = null;
};
$scope.parseLanguage = function() {
return TranslateService.detectLanguage($scope.myWords).then(function(response) {
console.log($scope.sourceLanguage);
$scope.sourceLanguage = response.data.sourceLanguage;
return console.log($scope.sourceLanguage);
});
};
return $scope.init();
}
]);
The console logs show the right data. But in the view, sourceLanguage never updates. Why would this be?
In case the promise you are evaluating is not part of the Angular context you need to use $scope.$apply:
$scope.parseLanguage = function() {
TranslateService.detectLanguage($scope.myWords).then(function(response) {
$scope.$apply(function() {
$scope.sourceLanguage = response.data.sourceLanguage;
});
});
};

Resources