I have been trying to send data from one controller to another. A little background this is code being used in an ionic application if that helps any. I want the to send the data from send() function to the SubCtrl. The send function is being called in MainCtrl. I have created a service for this but the data is still not being shared. What am I missing to complete this action?
var app = angular.module('testapp', []);
app.config(function($stateProvider, $urlRouterProvider) {
"use strict";
/* Set up the states for the application's different sections. */
$stateProvider
.state('page2', {
name: 'page2',
url: '/page2',
templateUrl: 'page2.html',
controller: 'MainCtrl'
})
.state('page3', {
name: 'page3',
url: '/page3',
templateUrl: 'page3.html',
controller: 'SubCtrl'
});
$urlRouterProvider.otherwise('/page2');
});
app.factory('dataShare', function($rootScope) {
var service = {};
service.data = false;
service.sendData = function(data) {
this.data = data;
$rootScope.$broadcast('data_shared');
console.log(data);
};
service.getData = function() {
return this.data;
};
return service;
});
app.controller('MainCtrl', function($scope, $state, $http, dataShare) {
$scope.text = 'food';
$scope.send = function() {
dataShare.sendData(this.text);
};
});
app.controller('SubCtrl', function($scope, $state, dataShare) {
"use strict";
var sc = this;
$scope.text = '';
$scope.$on('data_shared', function() {
var text = dataShare.getData();
sc.text = dataShare.data;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script id="page2.html" type="text/ng-template">
<div>{text}}</div>
<input type='text' ng-model='text' />
<button class="button button-outline button-royal" ng-click="send();">add</button>
</script>
<script id="page3.html" type="text/ng-template">
<div>text: {{text}}</div>
</script>
I was able to figure this issue out after reading this page. If anyone is having a similar issue I would encourage this reading. Also the video link on this post was really helpful.
Related
First time doing an angular application, combining different tutorials but this is the first time I am trying to inject a service.
I have one of my View's controllers like:
angular.module("myApp.Pages").controller('signupController', ['$scope', '$location', '$timeout', 'authService', function ($scope, $location, $timeout, authService) {
}
however am seeing an error when I look at the Console in Developer Tools:
angular.js:12793 Error: [$injector:unpr] Unknown provider:
authServiceProvider <- authService <- signupController
http://errors.angularjs.org/1.5.0-beta.2/$injector/unpr?p0=authServiceProvider%20%3C-%20authService%20%3C-ignupController
My project structure is:
-Client
-App
-Components
-Services
-authService.js
-myAppCore.js
-Views
-app.js
-appRouting.js
-Scripts (References)
-Theme (Css)
-Index.html
My index.html scripts I add:
<!-- Angular References-->
<script src="References/Angular/angular.js"></script>
<script src="References/Angular/angular-route.js"></script>
<script src="References/Angular/angular-ui-router.min.js"></script>
<!-- End Angular References-->
<!-- my app and dependent modules -->
<script src="App/app.js"></script>
<script src="App/appRouting.js"></script>
<!-- Services -->
<script src="App/Components/Services/authService.js"></script>
<!-- END services-->
<!-- Controllers for your pages-->
<script src="App/Pages/Home/homeController.js"></script>
<script src="App/Pages/ContactUs/contactusController.js"></script>
<script src="App/Pages/Entry/entryController.js"></script>
<script src="App/Pages/Signup/signupController.js"></script>
<!-- End Controllers for the page-->
My app.js
angular.module("myApp", [
// User defined modules
'myApp.Templates', // templates
'myApp.Pages', // Pages
'myApp.Core', // Core
// Angular modules
'ui.router', // state routing
'ngRoute', // angular routing
'angular-loading-bar', //loading bar
'LocalStorageModule', //local browser storage
])
and appRouting.js
angular.module("myApp")
.config(["$stateProvider", function ($stateProvider) {
$stateProvider.state('Home', {
url: '/Home',
templateUrl: 'App/Pages/Home/home.html',
controller: 'homeController'
})
.state('Entry', {
url: '/Entry',
templateUrl: 'App/Pages/Entry/entry.html',
controller: 'entryController'
})
.state('Signup', {
url: '/Signup',
templateUrl: 'App/Pages/Signup/signup.html',
controller: 'signupController'
})
.state('Contactus', {
url: '/Contactus',
templateUrl: 'App/Pages/ContactUs/contactus.html',
controller: 'contactusController'
})
.state("otherwise", {
url: "*path",
templateUrl: "App/Pages/NotFound/notFound.html"
});
}])
.run(["$location", function ($location) {
// Go to state dashboard
$location.url('/Home');
}]);
authService which handles login/register:
app.factory('authService', ['$http', '$q', 'localStorageService', function ($http, $q, localStorageService) {
var serviceBase = '<location>';
var authServiceFactory = {};
var _authentication = {
isAuth: false,
userName: ""
};
var _saveRegistration = function (registration) {
_logOut();
return $http.post(serviceBase + 'api/account/register', registration).then(function (response) {
return response;
});
};
var _login = function (loginData) {
var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password;
var deferred = $q.defer();
$http.post(serviceBase + 'token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function (response) {
localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName });
_authentication.isAuth = true;
_authentication.userName = loginData.userName;
deferred.resolve(response);
}).error(function (err, status) {
_logOut();
deferred.reject(err);
});
return deferred.promise;
};
var _logOut = function () {
localStorageService.remove('authorizationData');
_authentication.isAuth = false;
_authentication.userName = "";
};
var _fillAuthData = function () {
var authData = localStorageService.get('authorizationData');
if (authData) {
_authentication.isAuth = true;
_authentication.userName = authData.userName;
}
}
authServiceFactory.saveRegistration = _saveRegistration;
authServiceFactory.login = _login;
authServiceFactory.logOut = _logOut;
authServiceFactory.fillAuthData = _fillAuthData;
authServiceFactory.authentication = _authentication;
return authServiceFactory;
}]);
myAppPages.js and myAppCore.js are the same just their respective names :
angular.module("myApp.Pages", []);
Edit: Seeing a "app is not defined" reference error in authService
You don't defined var app, so use angular.module("myApp") to define your factory
angular.module("myApp").factory('authService', ['$http', '$q', 'localStorageService', function ($http, $q, localStorageService)
Also you can declare var app = angular.module("myApp") and use app
I simply did not declare:
var app = angular.module(...)
And my service was referencing app when that did not exist.
I can't figure out how to destroy my cache to get a new list from my server.
When I get the first list, it's work perfect, but after inserting informations to my database and sending another get to my server, the browser only show the cached version of my list, without the new data.
I tried to use cacheFactory like this:
$cacheFactory.get('$http').removeAll();
but it doesn't worked.
Here is my angular Module, Service and Controller.
Module myApp
var app = angular.module('myApp', ['ngRoute', 'LocalStorageModule', 'angular-loading-bar', 'smart-table']);
app.config(function ($routeProvider) {
$routeProvider.when("/home", {
controller: "homeController",
templateUrl: "/web/views/home.html"
});
$routeProvider.when("/cidades", {
controller: "cidadesController",
templateUrl: "/web/views/basico/cidades/cidades.html"
});
$routeProvider.otherwise({ redirectTo: "/home" });
});
app.config(function ($httpProvider) {
$httpProvider.interceptors.push('authInterceptorService');
});
app.run(['authService', function (authService) {
authService.fillAuthData();
}]);
cidadesService
'use strict';
app.factory('cidadesService', ['$http', '$cacheFactory', function ($http, $cacheFactory) {
var serviceBase = 'http://localhost:22207/';
var serviceFactory = {};
var _getCidades = function () {
$cacheFactory.get('$http').removeAll(); //This doesn't worked
return $http.get(serviceBase + 'api/cidades/getall').then(function (results) {
return results;
});
};
serviceFactory.getCidades = _getCidades;
return serviceFactory;
}]);
cidadesController
'use strict';
app.controller('cidadesController', ['$scope', 'cidadesService', function ($scope, service) {
$scope.cidade = {
id: "",
nome:"",
};
$scope.message = "";
$scope.getCidades = function () {
service.getCidades().then(function (results) {
$scope.cidades = [];
$scope.collection = [];
$scope.cidades = results.data;
$scope.collection = [].concat($scope.cidades);
}, function (err) {
$scope.message = err.error_description;
});
};
//Initializing the list
$scope.getCidades();
}]);
I really don't see anything wrong, but in any case you can add unique param for your request to prevent caching
like
$http.get(serviceBase + 'api/cidades/getall?unique=' + new Date().getTime())
I am integrating some Angular and ui-router into my start-up's website and I have come across an issue with getting ui-router and ui-view to work. It lead to wonder what the / in the url property of .state points to. Does it point to where the Angular app is declared or somewhere else? Essentially I'd appreciate any feedback into how I can fix my issue. (See "careers" state in "App Module" code below to see what I am referring to)
As you can see here, it's not currently working.
App Module
var careersApp = angular.module("ultradiaCareers", ["ui.router", "services"]);
careersApp.config(function($stateProvider, $locationProvider){
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
$stateProvider
.state('careers', {
url: "/",
templateUrl: "openings.html",
controller: "CareersController"
})
.state('positions', {
url: "/position/:id",
templateUrl: "position.html",
controller: "PositionsController"
});
});
Controllers
angular.module("ultradiaCareers")
.controller('CareersController', ["$scope", "GetOpenings", function ($scope, GetOpenings) {
"use strict";
GetOpenings.openings.then(function (positions) {
$scope.openings = positions.data;
});
}])
.controller('PositionsController', ["$scope", "$http", "$stateParams", "GetOpenings", function ($scope, $http, $stateParams, GetOpenings) {
"use strict";
GetOpenings.openings.then(function (positions) {
$scope.openings = positions.data;
$scope.positon = positions.data[GetOpenings.getPositionById($scope.openings, $stateParams.id)];
});
}]);
Index HTML
<html>
<head></head>
<body ng-app="ultradiaCareers">
<div ui-view></div>
</body>
</html>
Service for JSON
var careersServices = angular.module("services", [])
.factory("GetOpenings", ["$http", function ($http) {
"use strict";
var GetOpenings = this, i;
GetOpenings.openings = $http.get("/careers/positions.json");
return {
openings: GetOpenings.openings,
getPositionById: function (data, value) {
for (i = 0; i < data.length; i++) {
if (data[i].pid == value) {
return i;
}
}
}
};
}]);
This may be the repeated question but the workaround I found for this issue is not working in my case thats why I am posting the question.
I've following service:
appRoot.service('MyService', function($rootScope) {
var Messenger = {
Temp: "",
TempId:"",
tempMethod: function(Id) {
TempId = Id;
$rootScope.$broadcast('FirstCtrlMethod');
}
};
return Messenger ;
});
In second controller:
appRoot.controller('SecondCtrl', function ($scope, $location, MyResource, NotificationService, MyService) {
$scope.invokeFirstCtrl= function() {
var Id = '2';
MyService.tempMethod(Id);
});
In first controller:
appRoot.controller('FirstCtrl', function ($scope, $compile, $filter, $modal, $sce, $location, NotificationService, MyService) {
$scope.$on('FirstCtrlMethod', function () {
alert('I am from frist controller');
});
});
Problem: The line "$rootScope.$broadcast('FirstCtrlMethod');" is executing as expected but it is not causing to fire event "$scope.$on('FirstCtrlMethod', function () {.." in the first controller.
I've used the differenct services in many places in my app in the same way and they are workig fine, I am not understanding why it is not working here.
putting comment as an answer...
I guess the other controller which is supposed to receive the event is not yet instatiated when you are $broadcasting the event.
Please try instantiating the other controller
Please see below working example
var app = angular.module('app', []);
app.service('MyService', function($rootScope) {
var Messenger = {
Temp: "",
TempId: "",
tempMethod: function(Id) {
TempId = Id;
$rootScope.$broadcast('FirstCtrlMethod');
}
};
return Messenger;
});
app.controller('homeCtrl', function($scope, MyService) {
$scope.invokeFirstCtrl = function() {
var Id = '2';
MyService.tempMethod(Id);
};
});
app.controller('FirstCtrl', function($scope) {
$scope.$on('FirstCtrlMethod', function() {
alert('I am from frist controller');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="homeCtrl">
<button ng-click="invokeFirstCtrl()">Invoke</button>
</div>
<div ng-controller="FirstCtrl">
</div>
</div>
Lets say i list all users in a list, when i click a user i want to route to a new view and get the data for the selected person.
What is the preferred way? Should i move the data i already got when i listed the users or should i create a new server call?
My first thought is to pass the data, but the problem with this is that the data the gets lost if the user refreshes the page.
What is the best practice to solve this?
Small example:
(function() {
var app = angular.module('app');
var controllerId = 'app.controllers.views.userList';
app.controller(controllerId, [
'$scope', 'UserService',function ($scope, userService) {
var vm = this;
vm.users = [];
userService.getAllUsers().success(function (data) {
vm.users= data.users;
});
var gotoUser = function(user) {
// Pass the user to UserDetail view.
}
}
]);
})();
<div data-ng-repeat="user in vm.users" ng-click="vm.gotoUser(user)">
<span>{{customer.firstname}} {{customer.lastname}}</span>
</div>
i now list the user details in UserDetail view, this view is now vulnerable against a browser refresh.
Typically most people just create a new server call, but I'll assume you're worried about performance. In this case you could create a service that provides the data and caches it in local storage.
On controller load, the controller can fetch the data from the service given the route params and then load the content. This will achieve both the effect of working on page refresh, and not needing an extra network request
Here's a simple example from one of my apps, error handling left out for simplicity, so use with caution
angular.
module('alienstreamApp')
.service('api', ['$http', '$q','$window', function($http, $q, $window) {
//meta data request functions
this.trending = function() {
}
this.request = function(url,params) {
var differed = $q.defer();
var storage = $window.localStorage;
var value = JSON.parse(storage.getItem(url+params))
if(value) {
differed.resolve(value);
} else {
$http.get("http://api.alienstream.com/"+url+"/?"+params)
.success(function(result){
differed.resolve(result);
storage.setItem(url+params,JSON.stringify(result))
})
}
return differed.promise;
}
}]);
I would say that you should start off simple and do a new server call when you hit the new route. My experience is that this simplifies development and you can put your effort on optimizing performance (or user experience...) where you will need it the most.
Something like this:
angular.module('app', ['ngRoute', 'ngResource'])
.factory('Users', function ($resource) {
return $resource('/api/Users/:userid', { userid: '#id' }, {
query: { method: 'GET', params: { userid: '' }, isArray: true }
});
});
.controller("UsersController",
['$scope', 'Users',
function ($scope, Users) {
$scope.loading = true;
$scope.users = Users.query(function () {
$scope.loading = false;
});
}]);
.controller("UserController",
['$scope', '$routeParams', 'Users',
function ($scope, $routeParams, Users) {
$scope.loading = true;
$scope.user = Users.get({ userid: $routeParams.userid }, function () {
$scope.loading = false;
});
$scope.submit = function () {
$scope.user.$update(function () {
alert("Saved ok!");
});
}
}]);
.config(
['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
$routeProvider
.when('/users', {
templateUrl: '/users.html',
controller: 'UsersController'
})
.when('/users/:userid', {
templateUrl: '/user.html',
controller: 'UserController'
})
.otherwise({ redirectTo: '/users' });
}
]
);