I'm trying to make an HTTP request to the Last.fm API using Angular.js but I can't get it to work. I have separated out my Angular js files and have compiled them into one single js file called scripts.js using Codekit. The order in which the files are compiled is:
angular.min.js
app.js
controllers.js
services.js
Here is what my files look like:
app.js
var app = angular.module('app', []);
controllers.js
app.controller('similarArtistsController', function($scope, similarArtistsService) {
$scope.artists = [];
similarArtistsService.getArtists().success(function(response) {
console.log(response);
});
});
services.js
app.factory('similarArtistsService', function($http) {
var similarArtists = {};
similarArtists.getArtists = function() {
return $http({
method: 'GET',
url: 'http://ws.audioscrobbler.com/2.0/?method=artist.getSimilar&api_key=MYLASTFMAPIKEY&format=json&limit=5&artist=Tame+Impala'
});
}
return similarArtists;
});
index.html
<body>
<div ng-app="app">
<div ng-controller="similarArtistsController"></div>
</div>
<script src="/js/compiled/scripts.js"></script>
</body>
In my console I see "Error: [$injector:unpr]" which I've learned to mean that the controller cannot resolve a dependency. In my case I believe it has something to with my service I'm injecting, but I don't know where the error lies.
Does compiling the scripts minify them too? If so, you need to declare your dependencies in an array...
app.controller('similarArtistsController', ['$scope', 'similarArtistsService', function($scope, similarArtistsService) {
$scope.artists = [];
similarArtistsService.getArtists().success(function(response) {
console.log(response);
});
}]);
app.factory('similarArtistsService', ['$http', function($http) {
var similarArtists = {};
similarArtists.getArtists = function() {
return $http({
method: 'GET',
url: 'http://ws.audioscrobbler.com/2.0/?method=artist.getSimilar&api_key=MYLASTFMAPIKEY&format=json&limit=5'
});
}
return similarArtists;
}]);
Without that, Angular uses parameter names to resolve dependencies. Many minifiers mangle those names.
Include your services before your controllers so the service is known at time of injection
Can you try switching to app.service('similarArtistsService', function($http) {}); since this will return the function instance as opposed to factory which will return the value.
When you declare your dependencies in AngularJS, don't close off the array until after the function. See square brackets of array:
controllers.js
app.controller('similarArtistsController', ['$scope', 'similarArtistsService', function($scope, similarArtistsService) {
// code in here
}]);
services.js
app.factory('similarArtistsService', ['$http', function($http) {
// code in here
}]);
Related
I have a server set up on localhost:5000 that has a JSON string that contains "Hello world"
I want my AngularJS application to fetch this data, and display it.
here is what I have.
this is the script getJSON.js
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$http({
method : "GET",
url : "localhost:5000"
}).then(function mySuccess(response) {
$scope.myWelcome = response.data;
}, function myError(response) {
$scope.myWelcome = response.statusText;
});
});
this is how I call it in my html
<div ng-app="myApp" ng-controller="myCtrl">
<p>Today's welcome message is:</p>
<h1>{{myWelcome}}</h1>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, $http) {
$http.get("localhost:5000")
.then(function(response) {
$scope.myWelcome = response.data;
});
});
</script>
now the "myWelcome" should be "Hello world" but it just displays myWelcome when I run the code.
the backend is fully working! I've done it with regular Angular but need it to work with AngularJS unfortunately.
Any advice?
This is not a full answer I see what you're trying to do. It looks like you're not calling the correct controller and your value never gets updated. Move your app definition into your script tags and remove the controller that you have there
//index.html
<script>
var app = angular.module('myApp', []);
</script>
// myCtrl.js
app.controller('myCtrl', function($scope, $http) {
$scope.myWelcome = 'test';
$http({
method : "GET",
url : "localhost:5000"
}).then(response) {
$scope.myWelcome = response.data;
}, catch(error) {
$scope.myWelcome = error;
});
});
Next check your network tab and see if the request is actually executed. If it is not then you're controller is not connected to the app properly. You should be able to set breakpoints at this time and see what is firing and what is not.
EDIT: Also make sure you're loading your js file into your view after the first script tag is fired. Otherwise 'app' will not be defined.
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
Here's a simple example of what i'm trying to do. I'll preface this by saying that i have been working as a maintainer for 3 weeks on an already built project in angular, and i have a minor, at best understanding of angular to date. i can work with the controllers and views and models, all that is fine. but when it comes time to understanding the dependency injection, i am stymied by vague errors. Now it's came time i need to learn about how the Injector works, so here's a small test app i have constructed for my own learning purposes. i do not actually know if this is the correct way to build an angular app at all. The documentation i find confusing at best.
html
<div ng-app="app">
<div ng-controller="EC as e">
</div>
</div>
javascript
var app = angular.module('app',[]);
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push(function($q, $window) {
return {
'request': function(config) {
config.headers['Authorization'] = 'bearer '+ $window.localStorage.token;
return config;
}
};
});
}]);
function EC($scope,$http,$window) {
var vm = this;
vm.api = function( resource ){
return ('https://api.website.com/v1/'+resource).replace('//','/');
};
$window.localStorage.token = 'foobar';
$http.put( vm.api('/users/me'), { loggedIn: true }).then(function(response){
$http.get( vm.api('/users/me') ).then.function(response){
vm.user = response.data;
});
});
}
EC.$inject = ['$scope','$http','$window'];
app.controller('EC',EC);
app.run();
I had assumed the line EC.$inject = ['$scope','$http','$window']; would insure that my controllers constructor would be called with those services, or whatever the hell they are called, as arguments. Apparently thats not the case. Can someone explain to me like i'm 5 how this works, and why i'm getting an error?
Error message:
Error: [$injector:modulerr] http://errors.angularjs.org/1.5.6/$injector/modulerr
It's just bad markup. Fiddle showing you working code
Change:
.then
.function(response) {
vm.user = response.data;
to
.then(function(response) {
vm.user = response.data;
Rewrote the controller block to follow more conventionaly injection. Might workout for ya. Also removed the double response callback from the $http calls and returned the $http.get() promise.
angular.module('app', [])
.config(['$httpProvider', function($httpProvider)
{
$httpProvider.interceptors.push(function($window)
{
return {
request: function(config)
{
config.headers['Authorization'] = 'bearer '+ $window.localStorage.token;
return config;
}
};
});
}])
.controller('EC', ['$scope', '$http', '$window', function($scope, $http, $window)
{
var buildApiString = function(resource)
{
return ('https://api.website.com/v1/'+resource).replace('//','/');
};
$window.localStorage.token = 'foobar';
$http.put(buildApiString('/users/me'), { loggedIn: true }).then(function()
{
return $http.get(buildApiString('/users/me')).then(function(response)
{
$scope.user = response.data
});
});
}]);
I need a ajax call inside the function but if i use $http i am getting $http is not defined pls suggest me my code is
<script type="text/javascript">
function ContactController($scope) {
$scope.contacts = ["hi#email.com", "hello#email.com"];
$scope.add = function() {
alert("panduuuu")
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
$http.get('http://localhost:8080/ProjectManagement/REST/Login/Check?usename='+usename+'&password='+password+'')
.success(function(data, status, headers, config,response){
alert("insideee")
var json = JSON.stringify(data);
var getresponseText = JSON.parse(json);
var value=getresponseText.responseText;
}).error(function(data, status, headers, config,response) {
});
}
}
</script>
Correctly Passing Params
You should pass parameters to a http request like this
$http.get('http://MyServerIP:ServerPort/APICall', { params: { user_id: $scope._id } })
Also you should make calles like this in a service or a factory to be reused if needed
Add Your Correct Services
you also forgot to add $http in your function, next to $scope
ContactController($scope, $http)
You need to inject the $http service to your controller like this :
<script type="text/javascript">
function ContactController($scope, $http) {
...
You haven't injected the $http service into your controller.
angular.module('myApp', [])
.controller('ContactController', ['$scope', '$http', function ($scope, $http){
//awesome stuff
});
<div ng-app="myApp">
<div ng-controller="ContactController">
</div>
</div>
On a side note you should avoid registering controllers like you are and use .controller or .service etc. Also the array notation allows Angulars dependency system to work if you intend on minifying your JS.
https://docs.angularjs.org/guide/controller
I have abstracted my working code from a controller into a factory, but it doesn't seem to be working and I can't find what's wrong. I opted for a factory rather than a service because I wanted to execute some code that defined the variable before returning that variable; I want to get result.station (a part of the data returned by the API), not the full result.
This is my code:
var app = angular.module("myApp", []);
app.factory('api', ['$http',
function($http) {
var station_list = [];
$http({
method: 'GET',
url: 'http://api.irail.be/stations/?format=json&lang=nl'
})
.success(function(result) {
station_list = result.station;
});
return {
Stations: function() {
return station_list;
}
};
}
]);
app.controller("myController", ['api', '$scope',
function(api, $scope) {
$scope.station_list = api.Stations();
$scope.title = "Stations";
}
]);
and a working example.
Try this:
.success(function(result) {
angular.copy(result.station, station_list);
});
You had a small error, you were replacing the array instead of populating it. I used angular.copy instead of the assignment in your factory and it works
http://plnkr.co/edit/sqgKcFZAcClmkfdXHhrz
The problem is that you are dealing with asynchronous nature of AJAX.
I would suggest to have a delegate method in controller, which will be called when the service call is complete.
Something like the following:
app.controller("myController", ['api', '$scope',
function(api, $scope) {
api.Stations( function(station_list) {
$scope.station_list = station_list;
});
$scope.title = "Stations";
}
]);
The following is a service method excerpt:
return {
Stations: function(delegate) {
if (delegate)
delegate(station_list);
return station_list;
}
};