Okay, I have this function in a service:
wikiServices = angular.module('wikiServices', []);
wikiServices.factory('newsService', function($http, $q){
var chosenNewsStory = "";
var getNewsStory = function(news_id, callback){
var deferred = $q.defer();
$http({
method: "GET",
url: "news/article/" + news_id
})
.success(function(newsStory){
deferred.resolve(newsStory);
console.log("RESOLVED " + newsStory);
});
return deferred.promise;
});
Controller 1:
wikiControllers = angular.module('wikiControllers', []);
wikiControllers.controller('ctrl1', ['$scope', 'newsService',
function($scope, newsService){
$scope.getNewsStory = newsService.getNewsStory(function(input){
newsService.getNewsStory(news_id);
};
});
Controller 2:
wikiControllers = angular.module('wikiControllers', []);
wikiControllers.controller('ctrl1', ['$scope', 'newsService',
$scope.watch('newsService.chosenNewsStory', function(newVal){
console.log(newVal);
});
});
Now, I have tried setting "chosenNewsStory" in the service a lot of places buyt I think I'm missing a key part of the whole JS-"experience".
I'm having trouble setting "var chosenNewsStory" in the service to the newsStory fetched from the server. How can I do this?
Thanks.
You should define get and set methods for the variable that is being shared, and return these as well. I would format your service like so:
wikiServices.factory('newsService', function($http, $q){
var chosenNewsStory = "";
return {
getNewsStory: function(news_id, callback){
var deferred = $q.defer();
$http({
method: "GET",
url: "news/article/" + news_id
}).success(function(newsStory){
deferred.resolve(newsStory);
console.log("RESOLVED " + newsStory);
});
return deferred.promise;
},
getNews: function() {
return chosenNewsStory;
},
setNews: function(story) {
chosenNewsStory = story;
}
}
});
Now you will be able to watch newsService.getNews() and set it with newsService.setNews(news)
Related
Looking at this Plunker from an answer on SO
Plunker example
Learning angular and in the controller there is a param cityName, I am not sure how that works.
What I am trying to do is that I have a myController.js file
var app = angular.module("sampleApp");
app.controller('TypeaheadCtrl',['$scope','search', function ($scope, search) {
$scope.displayed=[];
search.getResult(searchQuery)
.then(function (data) {
$scope.displayed = (data.records);
});
}]);
myService.js
angular.module('sampleApp').factory('search', ['$q', '$http', function ($q, $http) {
var sdo = {
getResult: function (searchQuery) {
var promise = $http({
method: 'GET',
url: 'http://somewhere.com'
params: {
q: "a"
}
});
promise.success(function (data, status, headers, conf) {
return data;
});
return promise;
}
}
return sdo;
}]);
I want to be able to call the service after the third character is typed in the typeahead box and pass the characters to the service
You should use typeahead-min-length="3" option on typeahead input element.
HTML
<input type="text" ng-model="result"
typeahead="suggestion for suggestion in getSuggestion($viewValue)"
typeahead-min-length="3"/>
Then have function inside controller which will again return a promise.
$scope.getSuggestion = function (searchQuery){
return search.getResult(searchQuery)
.then(function (data) {
return data.records;
});
};
Since you have used .success the data will get return getResult function.
Use .then to chain promise so that you can return a data from the success callback.
Service
angular.module('sampleApp').factory('search', ['$q', '$http', function($q, $http) {
var sdo = {
getResult: function(searchQuery) {
var promise = $http({
method: 'GET',
url: 'http://somewhere.com'
params: {
q: searchQuery //<-- pass parameter here
}
});
promise.then(function(response) {
//you could format data here and returned formatted result
//or you could also do some sort of validation or filtering on data
return response.data;
});
return promise;
}
}
return sdo;
}]);
change your service like this
app.factory('search', ['$q', '$http', function($q, $http) {
var sdo = {};
sdo.getResult = function(query) {
var deferred = $q.defer();
var url = "http://someurlpath/api/" + query;
$http.get(url)
.success(function(data) {
deferred.resolve(data.data);
}).error(function(msg, code) {
deferred.reject(msg);
});
return deferred.promise;
};
return sdo;
}]);
I get a problem in AngularJS when getting data from JSON using service factory ($resource)
services.factory('GetCustomerByEmailFactory', function ($resource) {
return $resource(url + '/customerService/getCustomerByMail?email=:email', {}, {
getByMail: { method: 'GET', params: {email: '#email'} }
});
});
this service works well
but the controller part doesn't work
app.controller('CustomerCreationCtrl', ['$scope','PostCustomerFactory', '$location','Subscription','AddNotificationFactory','$routeParams','GetCustomerByEmailFactory',
function ($scope, PostCustomerFactory, $location,Subscription,AddNotificationFactory,$routeParams,GetCustomerByEmailFactory) {
$scope.customer ={};
$scope.not ={};
$scope.aftercustomer ={};
$scope.createNewCustomer = function(){
Number($scope.customer.PhoneNumber);
$scope.customer.SubscriptionDate = "1990-02-23T00:00:00";
$scope.customer.ManagerIdCustomer=1;
PostCustomerFactory.create($scope.customer);
var customer = GetCustomerByEmailFactory.getByMail({email:$scope.customer.Email}).$promise;
customer.then(function (responce){
$scope.aftercustomer = responce;
window.alert($scope.aftercustomer.Id);
$scope.not.CustomerId = $scope.aftercustomer.Id;
$scope.not.ManagerId = $routeParams.id;
AddNotificationFactory.create($scope.not);
});
$location.path("/login");
};
}]);
the window.alert show me an undefined value so that it doesn't get the data
I'm trying to abort the previous request if the user makes a new request. I wrote the code below, but requests are still running in parallel. Does anyone know what I'm doing wrong?
Controller
AppControllers.controller('HomeController',
['$scope', 'Services', '$q', function($scope, Services, $q) {
var canceler = $q.defer();
$scope.model = {};
$scope.find = function(id) {
canceler.resolve();
canceler = $q.defer();
Services.find(id, canceler).get().$promise.then(function(result) {
$scope.model = result;
});
};
}]);
Services
AppServices.factory("Services", ['$resource', function($resource) {
var factory = {};
var serviceBase = 'https://localhost/';
factory.find = function(id, canceler) {
return $resource(serviceBase + 'api/find/:Id', {Id: id}, {
get: {
method: 'GET',
isArray: false,
timeout: canceler.promise
}
});
};
return factory;
}]);
Why not available $scope.reserved of the variable in runtime? In template {{reserved}} is ок, but in controller value = undefibed.
I have the following code
Service:
'use sctict'
angular.module('starter.services', [])
.service('api', ['$http', '$q', function api($http, $q) {
var server = 'http://localhost/ires-api';
var jsondata = {
getReservedHours: function (masters, date) {
var deferred = $q.defer();
var promise = $http({ method: 'GET', url: server + '/reservations/' + masters + '/' + date, cache:true})
.success(function(response) {
//return response;
deferred.resolve({
data: response
});
}).error(function(msg, code) {
deferred.reject(msg);
$log.error(msg, code);
});
return deferred.promise;
},
}
return jsondata;
}]);
Controller
$scope.click = function(){
masters = [5,51];
api.getReservedHours(masters, '2007/08/27').then(function(response) {
$scope.reserved = response.data;
});
console.log($scope.reserved); // undefined ....
}
I think you're missing the assignment?
api.getReservedHours(masters, '2007/08/27').then(function(response) {
$scope.reserved = response.data;
});
Because "getReservedHours" is an asynchronous request and $scope.reserved is undefined (because the request is not complete) when you print it. Use this code instead
$scope.click = function(){
masters = [5,51];
api.getReservedHours(masters, '2007/08/27').then(function(response) {
$scope.reserved = response.data;
console.log($scope.reserved); // This would work
});
console.log($scope.reserved); // undefined ....
}
I am a Angular noob and having problems with binding a variable from one of my services to one of my controllers. I have read at least a dozen posts on the subject and nothing seems to be working for me.
Here is the controller:
app.controller('TeamController', ['$scope', '$modal', 'teamService', function ($scope, $modal, teamService) {
$scope.teamService = teamService;
$scope.selectedTeam = null;
$scope.selectTeam = function(teamId){
$scope.selectedTeam = teamService.getTeam(teamId, $scope.login.loginId);
};
}]);
Here is the service:
angular.module('teamService', [])
.service('teamService', function($http, $q){
this.selectedTeam = {teamId:-1, teamName:"Select a team", teamLocationName:"", teamDescription:"", teamManaged:false};
this.userTeams = [];
this.getTeam = function(teamId, loginId) {
var postData = {teamId: teamId, loginId: loginId};
var promise = $http({
url: "/url-for-getting-team",
method: "POST",
data: postData
});
promise.success(function (data) {
if (data.status === "success") {
this.selectedTeam = data.response;
return data.response;
}
});
promise.error(function () { //TODO handle getTeam errors
return {};
});
};
this.getSelectedTeam = function(){
return this.selectedTeam;
};
});
And here is the template:
<div class="jumbotron main-jumbo" ng-controller="TeamController">
<h1>{{selectedTeam.teamName}}</h1>
</div>
I have tried binding to the getSelectedTeam function and the service variable itself. Do I need to set up a $watch function in the controller? Any assistance would be greatly appreciated.
EDIT:
I tried turning my service into a factory, which still did not help me, so then I looked at a provider that was properly working that I had already written in the application. I converted my "teamService" into a provider and finally worked like a charm. Thanks for the contributions guys.
Code from my new provider:
angular.module('teamService', [])
.provider('teamService', function () {
var errorState = 'error',
logoutState = 'home';
this.$get = function ($rootScope, $http, $q, $state) {
/**
* Low-level, private functions.
*/
/**
* High level, public methods
*/
var wrappedService = {
/**
* Public properties
*/
selectedTeam: {teamName:"Select a team"},
userTeams : null,
createTeam: function(loginId, name, description, locationName, managed){
var postData = {loginId:loginId, teamName:name, teamDescription:description, teamLocationName:locationName, teamManaged:managed};
var promise = $http({
url: "/create-team-url",
method: "POST",
data: postData
});
return promise;
},
getTeam: function(teamId, loginId) {
var postData = {teamId: teamId, loginId: loginId};
var promise = $http({
url: "/get-team-url",
method: "POST",
data: postData
});
promise.success(function (data) {
if (data.status === "success") {
wrappedService.selectedTeam = data.response;
}
});
promise.error(function () { //TODO handle getTeam errors
wrappedService.selectedTeam = {};
});
},
getUserTeams: function(loginId) {
var postData = {loginId: loginId};
var promise = $http({
url: "/team-list-url",
method: "POST",
data: postData
});
return promise;
},
joinTeam: function(teamId, loginId){
var postData = {teamId:teamId, loginId:loginId};
var promise =$http({
url: "/join-team-url",
method: "POST",
data: postData
});
return promise;
},
getSelectedTeam: function(){
return wrappedService.selectedTeam;
}
};
return wrappedService;
};
});
As seen in my edit. I converted my service into a provider and all the changes seem to propagate to the view with no issues. I need to further analyze the difference between the factory, service, and provider in order to gain a higher understanding of what is going on here.
The main issue with the code is the way that promises are used. You can either correct that within the service, or handle it in the controller. As an example of the latter, you can re-write the above as:
Controller Code:
app.controller('TeamController', ['$scope', '$modal', 'teamService', function ($scope, $modal, teamService) {
$scope.teamService = teamService;
$scope.selectedTeam = null;
$scope.selectTeam = function(teamId){
teamService.getTeam(teamId, $scope.login.loginId).then(
function(result){
$scope.selectedTeam = result.data;
},
function(error){
console.log(error);
}
)
};
}]);
Service code:
angular.module('teamService', [])
.service('teamService', function($http, $q){
this.selectedTeam = {teamId:-1, teamName:"Select a team", teamLocationName:"", teamDescription:"", teamManaged:false};
this.userTeams = [];
this.getTeam = function(teamId, loginId) {
var postData = {teamId: teamId, loginId: loginId};
return $http({
url: "/url-for-getting-team",
method: "POST",
data: postData
});
};
this.getSelectedTeam = function(){
return this.selectedTeam;
};
});
You can also handle this in the service itself, but it requires a little more code. The key thing is that the getTeam call is asynchronous and needs to be handled using proper promise constructs.