I am trying to create a factory to retrieve weather data for a simple web page I am creating but, I am getting stuck when trying to call the function in the factory. I have fallowed Dan Wahlin's course on Udemy but I just cant figure out why I am getting the error. It definitely seems like I am doing something wrong but I can't figure it out.
Here is code
HTML
<!DOCTYPE html>
<div ng-controller="WeatherController" style="position:absolute; top:0px; ">
{{weather.weather.main}}<br>
<img src='http://openweathermap.org/img/w/10d.png' height="100px" width="100px">
</div>
<div style="background-color:white; position: absolute; bottom:0px;">
<canvas id="canvas" width="400" height="400">
</canvas>
</div>
<script src="script/angular.min.js"></script>
<script src="app/app.js"></script>
<script src="app/services/WeatherFactory.js"></script>
<script src="app/controllers/WeatherController.js"></script>
<script src="script/clock.js"></script>
app.js
(function () {
angular.module('displayApp', []);
}());
WeatherController.js
(function () {
var WeatherController = function ($scope, $log, $http, weatherFactory) {
$scope.weather = "";
function init() {
weatherFactory.getWeather() //******This line stops with error*****
.then(function (response) {
$scope.weather = response.data;
}, function (data, status, headers, config) {
$log.log(data.error + ' ' + status);
});
// $scope.weather = "Get the weather?"
}
init();
};
WeatherController.$inject = ['$scope', 'weatherFactory'];
angular.module('displayApp').controller('WeatherController', WeatherController);
}());
WeatherFactory.js
(function () {
var weatherFactory = function ($http) {
var factory = {};
factory.getWeather = function () {
//return $http.get('api.openweathermap.org/data/2.5/weather?q=Rancho Santa Margarita&appid=60f84f7ee9256ef5057de8b616105ab9');
return "Get the weather";
};
return factory;
};
weatherFactory.$inject = ["$http"];
angular.module('displayApp').factory('weatherFactory', weatherFactory);
}());
Specific error is
Cannot read property 'getWeather' of undefined
at init (WeatherController.js:17)
What am I missing, or what am I doing wrong?
Any and all help is appreciated.
Thanks.
You are missing a few injections. You currently have:
WeatherController.$inject = ['$scope', 'weatherFactory'];
And your arguments are $scope, $log, $http, weatherFactory. Just add the missing injections:
WeatherController.$inject = ['$scope', '$log', '$http', 'weatherFactory'];
Related
angular js not displaying anything even like simple expressions. i am tying to execute below code but no hope. can anyone help me out.
below code is for view to display.
`<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script type="text/javascript" src="/../../Scripts/angularsample.js"></script>
</head>
<body ng-app="spiceApp">
<div>
<div ng-controller="SpicyController">
<p> lets try some code by using service </p>
<input ng-init="message='Girish'" ng-model="message" />
<button ng-click="notify(message);">Notify{{1+2}}</button>
<p>alert will display only by clicking three times.</p>
</div>
<div ng-controller="List">
<button ng-click="bringList()">getList</button>
<table>
<tr ng-repeat="app in appslist">
<td>
{{app.Name}}
</td>
</tr>
</table>
</div>
</div>
</body>
</html>`
js code
var myApp = angular.module('spiceApp', []);
myApp.controller('SpicyController', ['$scope', '$http', 'userService', , function ($scope, $http, userService) {
//below code is using sservice
$scope.notify = function (msg) {
userService(msg);
};
}]);
myApp.controller('List', ['$scope', 'getList', function ($scope, getList) {
$scope.bringList = function () {
getList.getAppsList().then(function (list) {
$scope.appslist = list;
});
};
}]);
myApp.factory('getList', ['$http',function ($http) {
//this code for getting list from controller.
return getList.getAppsList=function(){
$http({
method: 'GET',
url: 'Home/GetAppsList'
})
.success(function (response) {
return response.data;
}, function (error) {
console.log(error);
});
}
}]);
myApp.factory('userService', ['$window', function (win) {
var msgs = [];
return function (msg) {
msgs.push(msg);
if (msgs.length == 3) {
win.alert(msgs.join('\n'));
msgs = [];
}
};
}]);`
please tell me where i am wrong. nothing is working. expression is displaying like {{1+2}} in the ouptut.
You have a typo here:
myApp.controller('SpicyController', ['$scope', '$http', 'userService', , function
with the 2 comas so the dependancies are messed up.
i tried in different way with same view but i modified the js file now it's working fine.
var myApp = angular.module('spiceApp', []);
myApp.controller('SpicyController', ['$scope', '$http', 'userService',function ($scope, $http, userService) {
//below code is using sservice
$scope.notify = function (msg) {
userService(msg);
};
}]);
myApp.factory('userService', ['$window', function (win) {
var msgs = [];
return function (msg) {
msgs.push(msg);
if (msgs.length == 3) {
win.alert(msgs.join('\n'));
msgs = [];
}
};
}]);
myApp.controller('List', ['$scope', 'getList', function ($scope, getList) {
$scope.bringList = function () {
getList.getAppsList.then(function (data) {
$scope.appslist = data;
});
};
}]);
var getList = angular.module("spiceApp").factory("getList", ['$http', function ($http, getList) {
return {
getAppsList: (function (response) {
return $http({
method: 'GET',
url: 'GetAppsList'
})
.then(function (response) {
console.log("coming from servicejs", response.data);
//return data when promise resolved
//that would help you to continue promise chain.
return response.data;
});
})()
};
return getList;
}]);
So I am sure I am not using best practices, but, I'm just trying to get this to work. I'm making a note taking app, and for whatever reason, the service I created, returns undefined and I can't figure out why.
Here's the service:
angular.module('notesService', []).factory('Notes', ['$http', function($http){
return {
get : function(){
var notes = $http.get('/api/notes');
return notes;
}
}
}]);
And here is the controller:
angular.module('mainController', [])
.controller('mainController', function($scope, Notes){
console.log(Notes.get());
});
The controller is not producing anything on the page just yet, i'm still testing.
Here is what the service returns to my controller:
e {
$$state : {
status : 1,
value : {
config : Object,
data: Array[10]
}
}
}
This isn't the entire thing, but it is all the stuff I need for my purposes.
Whenever I access $$state.value it returns undefined and I have no idea why.
You have the service in an entirely different module. So you gotta inject notesService into angular.module('mainController', [notesService]).
You dont ideally need to add new module for each controller and services, you can have single module and add everything to it
$http return a promise see documentation for $http
Also there is no need of the empty array in the angular.module parameter [] this might be what causes the error see in console.
angular.module('notesService').factory('Notes', ['$http', function($http){
return {
get : function(){
return $http.get('/api/notes');
}
}
}]);
angular.module('mainController')
.controller('mainController', function($scope, Notes){
Notes.get().then(function(result){
console.log(result);
})
});
I created an application that will help you to learn the best practices, plus solve your current problem.
//--In app.module.js--//
angular.module('notesApp', []);
//-- In app.controller.js--//
angular.module('notesApp')
.controller('MainController', ['$scope', '$http', '$log', 'notesFactory',
function($scope, $http, $log, notesFactory) {
$scope.data = {};
notesFactory.getData('http://localhost:3000/api/notes', 'GET')
.then(function(response) {
$log.log(response.data);
}, function(error) {
$scope.data = error;
});
}
]);
//--In app.service.js --//
angular.module('notesApp')
.factory('notesFactory', ['$http',
function($http) {
var notesService = {};
notesService.getData = function(url, method) {
return $http({
url: url,
method: method
});
}
return notesService;
}
]);
<html ng-app='notesApp'>
<head>
<title>
Notes Application
</title>
</head>
<body>
<div ng-controller='MainController'>
<pre>{{ data | json}}</pre>
</div>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js'></script>
<script src='app.module.js'></script>
<script src='app.controller.js'></script>
<script src='app.service.js'></script>
</body>
</html>
Check the console for the json object as shown in the screenshot
I wanna use multiple ( in this case, 2 ) $http.gets in my service !
As you know the simple form of using $http.get is this :
app.factory('MyService', function ($http, $q) {
return {
getData: function() {
return $http.get('myfile.json')
.then(function(response) {
return response.data;
});
}
};
});
Now I wanna use 2 files ( 2 $http.gets ) and compare them to each other ( with some for loops and etc that I can ... ) !
What can I do now ? :(
use $q.all.
Add $q to controller's dependencies, exemple
$scope.req1 = $http.get('myfile.json');
$scope.req2 = $http.get('myfile2.json');
$q.all([$scope.req1, $scope.req2]).then(function(data) {
// data is array of your files
if ( JSON.stringify(data[0]) === JSON.stringify(data[1])){
console.log('is equal');
}
});
It is an extension of Hajji Tarik's solution. I was able to derive from your comments that you were still not clear with what to code in where. So I have developed a sample application which will assist you for the same.
//--app.module.js--//
angular.module('notesApp', []);
//--app.service.js--//
angular.module('notesApp')
.factory('notesFactory', ['$http',
function($http) {
var notesService = {};
notesService.getData = function(url, method) {
return $http({
url: url,
method: method
});
}
return notesService;
}
]);
//--app.controller.js--//
angular.module('notesApp')
.controller('MainController', ['$scope', '$http', '$log', '$q', 'notesFactory',
function($scope, $http, $log, $q, notesFactory) {
$scope.data = {};
var data1 = notesFactory.getData('http://localhost:3000/api/notes/1', 'GET');
var data2 = notesFactory.getData('http://localhost:3000/api/notes/2', 'GET');
var combinedData = $q.all({
firstResponse: data1,
secondResponse: data2
});
combinedData.then(function(response) {
$log.log(response.firstResponse.data);
$log.log(response.secondResponse.data);
//Write your comparison code here for comparing json results.
}, function(error) {
$scope.data = error;
});
}
]);
<html ng-app='notesApp'>
<head>
<title>
Notes Application
</title>
</head>
<body>
<div ng-controller='MainController'>
</div>
<script src='https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js'></script>
<script src='app.module.js'></script>
<script src='app.controller.js'></script>
<script src='app.service.js'></script>
</body>
</html>
When I run my Application in Browser, the console tells me :
Error: [ng:areq] Argument 'FlightListController' is not a function, got undefined
'FlightListController' is bound to my index.html via "ng-view"
<div class="container" ng-view="FlightListController"></div>
and is imported accordingly at the end of my index.html
<script src="app/controller/FlightListController.js"></script>
The FlightListController.js content is:
var app = angular.module("flightlog");
app.controller("Flight", function ($scope, $http) {
$http.get("http://localhost:3000/flights").success(function (response) {
$scope.flights = response;
}).error(function (err) {
$scope.error = err;
});
Now i don't have any clue what the Angular Error wants to tell me. The Link hidden behind the error doesn't really help.
var app = angular.module("flightlog");
app.controller("FlightListController", ['$scope', '$http', function ($scope, $http) {
$http.get("http://localhost:3000/flights").success(function (response) {
$scope.flights = response;
}).error(function (err) {
$scope.error = err;
});
}]);
HTML:
<div class="container" ng-controller="FlightListController">
If I am not wrong you are telling the view wich is his controller you should use:
ng-controller not ng-view
<div class="container" ng-controller="FlightListController">
https://docs.angularjs.org/api/ng/directive/ngController - Documentation
var nameSpace = angular.module("MyTutorialApp", []);
nameSpace.controller("MainController", ['$scope', '$http',
function($scope, $http)
{
$http.get("../api/api.php?fxn=" + encodeURIComponent("getCategories") +
"&jsn=" + encodeURIComponent("{'code':'1'}"))
.success(function(response)
{
$scope.names = response;
});
$scope.myData = {};
nameSpace.controller("MainController", ['$scope', '$http',
$scope.myData.doClick = function($event, name, $scope, $http,$config)
{
alert(name);
var element = name;
console.log(element);
$http.get("../api/api.php?fxn=" + encodeURIComponent("getSubCategories") +
"&jsn=" + encodeURIComponent("{'code':'element'}"))
.success(function(response)
{
$scope.subCat = response;
});
}]);
}
]);
<!DOCTYPE html>
<head>
<title>Learning AngularJS</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js" type="text/javascript"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script src="js/maincontroller.js"></script>
</head>
<body ng-app="MyTutorialApp" >
<div ng-controller="MainController">
<table class="table">
<tr class="row1" ng-repeat="list in names.category">
<td ng-click="myData.doClick($event,list.name)">{{ list.name }}</td>
</tr>
</table>
</div>
</body>
</html>
Hi, i m not able to make the second http request , It says get property undefined. I tried for quite along time, i am not able to spot what is going wrong. Kindly Help me. I am just starting to use angular.
To explain what I am trying to achieve , the first http request calls for the list of categories , the list is populated and after that on click of any of the category , the category is sent as the jsn for the second http request . And it fetch's the sub category
Check this
// Code goes here
var nameSpace = angular.module("MyTutorialApp", []);
nameSpace.factory('factoryRefrence', ['$http', '$q',
function($http, $q) {
return {
getCategories: function() {
var deferred = $q.defer();
$http.get("../api/api.php?fxn=" + encodeURIComponent("getCategories") +
"&jsn=" + encodeURIComponent("{'code':'1'}"))
.success(function(response) {
deferred.resolve(response);
});
return deferred.promise;
},
getsubCategories: function(element) {
var deferred = $q.defer();
$http.get("../api/api.php?fxn=" + encodeURIComponent("getSubCategories") +
"&jsn=" + encodeURIComponent({
'code': element
}))
.success(function(response) {
deferred.resolve(response);
});
return deferred.promise;
}
}
}
]);
nameSpace.controller("MainController", ['$scope', '$http', 'factoryRefrence',
function($scope, $http, factoryRefrence) {
factoryRefrence.getCategories().then(function(response) {
$scope.names = response;
});
$scope.myData = {};
$scope.myData.doClick = function(event, name) {
alert(name);
var element = name;
console.log(element);
factoryRefrence.getsubCategories().then(function(response) {
$scope.subCat = response;
});
}
}
]);
Demo
this is the way to communicate with functions in factory. if you setup like this it should work fine. and besides in your code you are defining controller twice which is not okay.