问题
I am new to AngularJS and I am trying to create custom service to encapsulate $http service. I have tried debugging but am not able to fix this. Could you please tell what am I doing wrong here. The function in the custom service returns a promise. I think the problem is there. When I replace the getUser code by console.log it doesn't give 'undefined' error.
<html ng-app="gitHubViewer">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../angular.min.js"></script>
<script src="search.js"></script>
<script src="github.js"></script>
<style>
.my-input {
color:black;
background: red;
}
</style>
</head>
<body ng-controller="MainController">
<div>
{{error}}
</div>
<h1><label>{{message}}</label></h1>
<label> {{countdown}}</label>
<form name="searchUserForm" ng-submit="search(username)">
<input type="search" required placeholder="Enter User Name" ng-model="username"/>
<input type="submit" value="Search"/>
</form>
<div ng-include="'userDetails.html'" ng-show="user"></div>
</body>
</html>
Controller:
(function(){
var app = angular.module("gitHubViewer",[]);
var MainController = function(
$scope,github,$interval,$log,
$location,$anchorScroll
){
var decrementCountdown = function() {
$scope.countdown--;
if($scope.countdown<1)
$scope.search($scope.username);
};
var onResultComplete = function(data) {
$scope.user=data;
github.getRepos($scope.user).then(onRepos,onError);
};
var onRepos = function(data) {
$scope.repos = data;
$location.hash("userDetails");
$anchorScroll();
};
var onError = function(reason) {
$scope.error ="Could not fetch data";
};
var countDownInterval = null;
var startCountdown = function() {
countDownInterval= $interval(decrementCountdown,1000,$scope.countdown);
};
$scope.search = function(username) {
$log.info("Searching for "+username);
github.getUser(username).then(onResultComplete,onError);
if(countDownInterval) {
$interval.cancel(countDownInterval);
$scope.countdown = null;
}
};
$scope.username="angular";
$scope.message="Git Hub Viewer";
$scope.orderReposByStar="-stargazers_count";
$scope.countdown = 5;
startCountdown();
};
app.controller('MainController',["$scope","github","$interval","$log","$location","$anchorScroll",MainController]);
}());
Custom Sevice:
(function(){
var github = function($http) {
var getUser = function(username) {
console.log("in github "+username);
$http.get("https://api.github.com/users/"+username).
then( function(response){
return response.data; //it would return the data wrapped in a promise as the call
//to 'then' returns a promise
});
};
var getRepos = function(user) {
$http.get(user.repos_url).
then(function(response){
return response.data;
});
};
return {
getUser: getUser,
getRepos: getRepos
};
};
var module = angular.module("gitHubViewer");
module.factory("github" ,["$http", github]);
}());
Error:
"Error: github.getUser(...) is undefined
MainController/$scope.search@file:///home/smitha/AngularJS/DirectivesAndViews2WriteOwnService/search.js:34:4
MainController/decrementCountdown@file:///home/smitha/AngularJS/DirectivesAndViews2WriteOwnService/search.js:11:5
fd/g.prototype.notify/<@file:///home/smitha/AngularJS/angular.min.js:115:162
Pe/this.$get</l.prototype.$eval@file:///home/smitha/AngularJS/angular.min.js:126:189
Pe/this.$get</l.prototype.$digest@file:///home/smitha/AngularJS/angular.min.js:123:278
Pe/this.$get</l.prototype.$apply@file:///home/smitha/AngularJS/angular.min.js:126:469
e/O.$$intervalId<@file:///home/smitha/AngularJS/angular.min.js:91:100
"
It could be very something simple. But I am not able to spot my mistake. It worked in the online turorial. Would be grateful for any pointers. Thanks.
回答1:
Had overlooked return from the functions in the gitHub service. Hence the undefined error. The corrected code is as below: github.js
(function(){
var github = function($http) {
var getUser = function(username) {
console.log("in github "+username);
return $http.get("https://api.github.com/users/"+username).
then( function(response){
return response.data;
});
};
var getRepos = function(user) {
return $http.get(user.repos_url).
then(function(response){
return response.data;
});
};
return {
getUser: getUser,
getRepos: getRepos
};
};
var module = angular.module("gitHubViewer");
module.factory("github" ,["$http", github]);
}());`
`
回答2:
there are several mistakes u have done,
calling getuser
by this way
github.getUser(username).then(onResultComplete,onError);
means that :
- github service returns a
getUser
function that accept one parameter getUser
function returns some method that have.then
function
but that dependencies dose not presented in your service implementation
so you have to change your service to something like that
angular.module('myApp.services', [])
.factory('githubService', ['$http', function($http) {
var doRequest = function(username, path) {
return $http({
method: 'JSONP',
url: 'https://api.github.com/users/' + username + '/' + path + '?callback=JSON_CALLBACK'
});
}
return {
events: function(username) { return doRequest(username, 'events'); },
};
}]);
and use it like that
app.controller('ServiceController', ['$scope', 'githubService',
function($scope, githubService) {
// uses the $http service to call the GitHub API
// and returns the resulting promise
githubService.events(newUsername)
.success(function(data, status, headers) {
// the success function wraps the response in data
// so we need to call data.data to fetch the raw data
$scope.events = data.data;
});
}]);
来源:https://stackoverflow.com/questions/28214639/i-get-custom-method-undefined-error-when-i-encapsulate-http-service-in-custom-s