i want to use my controller for getting images link of dog with an api but I am not able to use the result.
var images = function(breed) {
var promise = $http({
method: 'GET',
url: 'https://dog.ceo/api/breed/' + breed + '/images/random'
})
.then(function successCallback(response) {
return response.data.message;
},
function errorCallback(response) {
});
return promise;
}
console.log(images("kelpie"));
the problem is, i can't get the link in the object.
if I change response.data.message by only response.data, this is why i get
when I add console.log(response.data) before the return, this is what I get:
If I try JSON.parse(response.data), I got this:
Do you know how to do ?
Thank you for your help
What you are seeing in the console is the promise itself.
if you want to view the value (which in this case will be the url) then do it like this
console.log(images("kelpie").value);
If you want to see the response data then you need to add the console.log() in the then() callback.
Do it like this:
.then(function successCallback(response) {
console.log(response.data.message);
return response.data.message;
}
can you try one with JSON.parse(response.data) and then fetch message property from it.
You need to utilize promise here.
One way to do this is -
angular.module('demo', [])
.controller('myController', ['$scope', 'demoService', function($scope, demoService){
demoService.test().then(function(response) {
$scope.url = response;
})
}])
.factory('demoService', ['$http', '$q',
function($http, $q) {
var demoService = {};
demoService.test = function() {
var deferred = $q.defer();
$http.get('https://jsonplaceholder.typicode.com/posts/1').then(
function(response) {
response = "https://www.w3schools.com/bootstrap/paris.jpg";
deferred.resolve(response);
}, function(error) {
console.log("some error occur");
console.log(error);
deferred.reject(error);
}
)
return deferred.promise;
}
return demoService;
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demo" ng-controller="myController">
<img ng-src="{{url}}" />
</div>
Use promise deffer object
Refference - https://docs.angularjs.org/api/ng/service/$q
JS fiddle working code - https://jsfiddle.net/Shubhamtri/9y9ezkdt/1/
Related
AngularJS ng-repeat not changing when array changes
I have a controller:
<section data-ng-controller="FilmController">
<article data-ng-view></article>
</section>
This is its controller:
.controller('FilmController',
[
'$scope',
'dataService',
'$routeParams',
function ($scope, dataService, $routeParams) {
var getFilms = function(searchterm, category, page){
dataService.getFilms(searchterm, category, page).then(
function(response){
$scope.films = [];
$scope.films = response.data;
let pageLinks = [];
for (let i = 0; i < response.data[10][0]; i += 10) {
pageLinks.push({
pageLink: "/wai/wai-assignment/#/films?searchterm=" + searchterm + "&category=" + category + "&page=" + i/10,
pageNum: i/10
})
}
$scope.pageLinks = pageLinks;
console.log(pageLinks);
},
function(err){
$scope.status = 'Unable to load data' + err;
},
function(notify){
console.log(notify);
}
);
}
if ($routeParams && ($routeParams.searchterm || $routeParams.category)){
getFilms($routeParams.searchterm, $routeParams.category, $routeParams.page);
} else {
getFilms('','',$routeParams.page);
}
}
]);
These are the routes:
app.config(
[
'$routeProvider',
function ($routeProvider) {
$routeProvider
.when('/films', {
templateUrl: 'js/partials/films.html',
controller: 'FilmController'
})
.otherwise({
redirectTo: '/'
});
}
]
);
Here is the template:
<section>
<table>
<tr data-ng-repeat="film in films">
<td>{{film.title}}</td>
<td>{{film.name}}</td>
<td>{{film.description}}</td>
</tr>
</table>
<a data-ng-repeat="pageLink in pageLinks" ng-href="{{pageLink.pageLink}}">
{{pageLink.pageNum}}
</a>
</section>
When i access films?searchterm=example&category=example&page=1
It shows films with the category and search criteria from a database. When i click a link to go to a different page, it just grabs data from an SQL statement with a different OFFSET, but the ng-repeat doesn't update with it.
I know why this happens, something to do with scopes, but i can't work out how to fix it. Can anyone help?
EDIT:
angular.module('filmDirectoryApp')
.service('dataService',
[
'$q',
'$http',
function ($q, $http) {
var urlBase = 'server/';
var defer = $q.defer();
this.getFilms = function (searchterm, category, page) {
$http.get(urlBase + 'getfilms.php?searchterm=' + searchterm + '&category=' + category + '&page=' + page)
.success(function (response) {
console.log(response);
defer.resolve({
data: response
});
})
.error(function (err) {
defer.reject(err);
});
return defer.promise;
}
}
]
);
The code uses a deferred anti-pattern that is written incorrectly. The $q.defer only resolves once. Subsequent calls to defer.resolve are ignored. This is the way promises work.
In addition the .success and .error methods are deprecated and have been removed from the AngularJS framework.
The solution is to avoid the deferred anti-pattern and use the .then and .catch methods.
angular.module('filmDirectoryApp')
.service('dataService',
[
'$http',
function ($http) {
var urlBase = 'server/';
this.getFilms = function (searchterm, category, page) {
var params = {
"searchterm": searchterm,
"category" : category,
"page" : page
};
var config = { "params": params };
return $http.get(urlBase + 'getfilms.php', config)
.then(function (response) {
var data = response.data;
console.log(data);
return data;
})
.catch(function (err) {
console.log(err)
throw err;
});
}
}
]
);
The $http service deprecated custom callback methods - .success() and .error() - have been removed. You can use the standard .then()/.catch() promise methods instead, but note that the method signatures and return values are different.
The .then method returns a new promise which is resolved or rejected via the return value of the successCallback, errorCallback (unless that value is a promise, in which case it is resolved with the value which is resolved in that promise using promise chaining).
For more information, see
AngularJS $q Service API Reference - The Promise API
Is this a deferred anti-pattern?
Why were .success and error removed from the $http service?
This question already has answers here:
Why are AngularJS $http success/error methods deprecated? Removed from v1.6?
(2 answers)
Closed 3 years ago.
Getting this error:
angular.min.js:122 TypeError: $http.get(...).success is not a function
at getUserInfo (app.js:7)
at new (app.js:12)
at Object.invoke (angular.min.js:43)
at Q.instance (angular.min.js:93)
at p (angular.min.js:68)
at g (angular.min.js:60)
at g (angular.min.js:61)
at g (angular.min.js:61)
at angular.min.js:60
at angular.min.js:21
Here is my code:
var gitHub = angular.module('gitHub', []);
gitHub.controller('mainController', ['$scope', '$http', function($scope, $http) {
var $scope.user = '';
function getUserInfo($scope, $http){
$http.get('https://api.github.com/users')
.success(function (result) {
$scope.user = result;
console.log(result);
});
};
getUserInfo($scope, $http);
}]);
and here is the html
<!DOCTYPE html>
<html ng-app="gitHub">
<head>
<title>Github Users Directory</title>
<script src="angular.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="mainController">
<div>
<h1>GitHub Users</h1>
Who do you want to search for?<input type="text" name="FindHim" ng-model="queryName" />
<button ng-click="getUserInfo()">Search</button>
</div>
<div>
{{ user }}
</div>
</div>
</body>
</html>
The .success and .error methods are deprecated and have been removed from AngularJS 1.6. Use the standard .then method instead.
$http.get('https://api.github.com/users')
.then(function (response) {
var data = response.data;
var status = response.status;
var statusText = response.statusText;
var headers = response.headers;
var config = response.config;
$scope.user = data;
console.log(data);
});
Deprecation Notice
The $http legacy promise methods .success and .error have been deprecated and will be removed in v1.6.0. Use the standard .then method instead.
— AngularJS (v1.5) $http Service API Reference -- Deprecation Notice.
Also see SO: Why are angular $http success/error methods deprecated?.
i think you need to use .then and not .success when using angular.
Example from the doc's
var promise = asyncGreet('Robin Hood');
promise.then(function(greeting) {
alert('Success: ' + greeting);
}, function(reason) {
alert('Failed: ' + reason);
}, function(update) {
alert('Got notification: ' + update);
});
Here is the example of how $Http uses it:
// Simple GET request example:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
And finally your code could look like this
$scope.getUserInfo = function () {
$http.get('https://api.github.com/users')
.then(function (result) {
$scope.user = result;
console.log(result);
}, function(result) {
//some error
console.log(result);
});
};
this works
https://docs.angularjs.org/api/ng/service/$http
// Simple GET request example:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
As per your current implementation, You are not passing arguments (i.e. $scope and $http) to getUserInfo from ng-click="getUserInfo()" thus you are getting the error.
You don't need to pass these as arguments as $scope and $http as its already injected in controller and define the function in $scope.
gitHub.controller('mainController', ['$scope', '$http', function($scope, $http) {
$scope.user = '';
//Redefined function, without arguments
$scope.getUserInfo = function (){
$http.get('https://api.github.com/users')
.success(function (result) {
$scope.user = result;
console.log(result);
});
};
$scope.getUserInfo();
}]);
You dont need to inject $scope, $http..
app.controller('MainController', function($scope, $http) {
$scope.fetchData = function(_city){
$http.get("../api/AllPlaces?filter[where][placeCity]="+ _city)
.then(function(response) {
$scope.Data = response.data;
});
}
});
No need to pass $http as a function parameter, since you have already injected $http as a dependency to your controller. I have made some modification to the code. Please check it will work fine for you.
var gitHub = angular.module('gitHub', []);
gitHub.controller('mainController', ['$scope', '$http', function ($scope, $http) {
$scope.user = '';
$scope.getUserInfo = function() {
$http.get('https://api.github.com/users')
.success(function (result) {
$scope.user = result;
console.log(result);
});
};
$scope.getUserInfo();
}]);
According to Angular JS $http documentation, this system has been excludede from 1.4.3 + So, I have taken help from his post and you can try this way
app.controller('MainCtrl', function ($scope, $http){
$http({
method: 'GET',
url: 'api/url-api'
}).then(function (success){
},function (error){
});
}
OR
$http.get('api/url-api').then(successCallback, errorCallback);
function successCallback(response){
//success code
}
function errorCallback(error){
//error code
}
I prefer the second one which was more flexible for me.
$http({
method: 'GET',
url: '....',
headers: {
'Authorization': 'Bearer ' + localStorage["token"]
}
})
.then(function (data, status, headers, config) {
alert(JSON.stringify(data) + "Status" + status);
})
.error(function (data, status, headers, config) {
alert(JSON.stringify(data) + "Status" + status);
});
function successCallback(response) {
return response
}
$http.get('url')
.then(successCallback)
I need to finish all my ajax calls to enable a button, but I am not getting all my promises done before enabling the button.
I have this piece of code with all my ajax gets:
$q.all([
$scope.load_ocupacoes(),
$scope.load_tipos_pisos(),
$scope.load_tipos(),
$scope.load_caracteristicas(),
$scope.load_amenidades(),
$scope.load_subtipos(true, 'incluir')
]).then(function() {
console.log('loading complete !!!');
$scope.theglyphicon = 'fa fa-check fa-fw';
$scope.isDisabledButton = false;
});
Each load function is a $http.get, like that:
$scope.load_ocupacoes = function() {
$http.get(url_api_status_ocupacao)
.success(function(response) {
console.log(response);
$scope.status_ocupacoes = response;
})
.error(function(response) {
console.log(response);
ngToast.create({
className: 'danger',
content: 'Não foi possível recuperar a lista.'
});
});
};
I have also tried this way:
$scope.load_ocupacoes = function()
{$resource(url_api_status_ocupacao).query().$promise.then(function(response) {
console.log(response);
$scope.status_ocupacoes = response;
});
};
And this... but with the same problem:
$scope.load_ocupacoes = function() {
$timeout(function(){
$scope.$apply(function() {
$scope.status_ocupacoes = appFactory.recuperarLista(url_api_status_ocupacao)
.then(function(result) {
console.log(result);
$scope.status_ocupacoes = result;
});
});
});
};
But, I am getting the message 'loading complete !!!' before the end of all loading.
Is there any problem with this approach?
There could be more errors, but the basic misunderstanding is that $q.all takes promises, and all your functions return undefined (because they don't have a return statement) - so instead of getting six promises, your $q.all gets six undefineds. AFAIK, $http.get returns a promise by default, so one way to fix it would be to just add return statement to each of your functions, in front of $http.get, like this:
$scope.load_ocupacoes = function() {
return $http.get(url_api_status_ocupacao)
.then(function(response) {
});
};
I guess $q.all accept promises.
This must be apply to all other's related method.
$scope.load_ocupacoes = function() {
$http.get(url_api_status_ocupacao)
// use then instead success
.then(function(response) {
// return raw promise instead actual value
return response;
}, console.log('error));
};
$q.all requires an array of promises but your are providing a function which is neither returning any promise.
You can do this :
$q.all([
$http.get(url_api_status_ocupacao),
$http.get(url_api1),
$http.get(url_api2)
]).then(function() {
......
});
I have resolved my problem with this approach:
var promises = [appFactory.recuperarLista(url_api_status_ocupacao),
appFactory.recuperarLista(url_api_tipos_pisos),
appFactory.recuperarLista(url_api_caracteristicas),
appFactory.recuperarLista(url_api_amenidades)
];
$q.all(promises).then(function (responses) {
$scope.status_ocupacoes = responses[0];
$scope.tipos_pisos = responses[1];
$scope.caracteristicas = responses[2];
$scope.amenidades = responses[3];
}).then(function() {
console.log('All Loading completed !!!');
});
And I made a factory returning promises:
angular.module('starter.services', ['datatables'])
.factory('appFactory', function($http, $q) {
return {
recuperarLista: function(url) {
var deferred = $q.defer();
$http({ method: "GET", url: url })
.success(function (data, status, headers, config) {
deferred.resolve(data);
}).error(function (data, status, headers, config) {
deferred.reject(status);
});
console.log('loading for ' + url + ' was completed !!!');
return deferred.promise;
}
};
});
Now I am getting this console output:
loading for api/loadliststatusocupacoes was completed !!!
services.js:171
loading for api/loadlisttipospisos was completed !!!
services.js:171
loading for api/loadlistcaracteristicas was completed !!!
services.js:171
loading for api/loadlistamenidades was completed !!!
services.js:171
All Loading completed !!!
imovel-controller.js:690
I am using ASP.NET MVC5 and angularJS, i have just started learning angular and i'm not so sure on best practice. what i have archived so far is good however not sure if the best approach, all my backend code is finished and i return my results as json in the controller(mvc)
in regards to angularJS i have the following code, is this how it should be done? or there is something better? also the reason why i have ng-click call all methods is that i will have select-ui and passing params to retrieve new data.
note: i have removed a lot of partials the main dashboard has around 20...
main.js
var mainModule = angular.module("mainModule", []);
mainModule.factory("appService", ["$http", "$q", function ($http, $q) {
function getBookingData() {
var deferred = $q.defer(),
httpPromise = $http({ method: "GET", url: "/Main/BookingData" });
httpPromise.then(function(response) {
deferred.resolve(response);
}, function(error) {
console.error(error);
});
return deferred.promise;
}
function getCommissionData() {
var deferred = $q.defer(),
httpPromise = $http({ method: "GET", url: "/Main/CommissionsData" });
httpPromise.then(function(response) {
deferred.resolve(response);
}, function(error) {
console.error(error);
});
return deferred.promise;
}
return {
getBookingData: getBookingData,
getCommissionData: getCommissionData
};
}
]);
mainModule.controller("mainController", [
"$scope", "$q", "appService", function($scope, $q, appService) {
$scope.getObjects = function() {
appService.getBookingData()
.then(function(response) {
$scope.bookingArray = response.data;
console.log(response);
}, function(error) {
console.error(error);
});
appService.getCommissionData()
.then(function(response) {
$scope.commissionArray = response.data;
console.log(response);
}, function(error) {
console.error(error);
});
};
$scope.getObjects();
}
]);
index.cshtml
#{
ViewBag.Title = "Main";
}
<div class="wrapper wrapper-content" ng-app="mainModule" ng-controller="mainController">
<div class="row">
<button type="button" class="btn btn-warning" ng-click="getObjects()">Apply</button>
</div>
<div class="row">
<div class="col-lg-3 col-sm-6">
<div>#Html.Partial("_Booking")</div>
</div>
<div class="col-lg-3 col-sm-6">
<div>#Html.Partial("_Commission")</div>
</div>
</div>
</div>
#section Scripts {
#Scripts.Render("~/scripts/main")
}
Your appService code can be much cleaner. $http already returns promises from its calls, so you don't need any of the explicit $q calls.
function getBookingData() {
return $http({ method: "GET", url: "/Main/BookingData" })
.catch(function (error) { console.error(error); });
}
Is equivalent to your function. It might be good to review how the promise API works, and experiment with some test projects.
It doesn't look like you do anything with $scope.bookingArray and $scope.commissionArray, but maybe it's in the partials you omitted?
First of all, Albert Liu's answer regarding promises are correct. I think you can reduce your factory code to this using $http shortcut methods:
mainModule.factory("appService", ["$http", function ($http) { // no need to inject $q
function getBookingData() {
return $http.get("/Main/BookingData"); // $http.get shortcut methods returns a promise
}
function getCommissionData() {
return $http.get("/Main/CommissionsData"); // $http.get shortcut methods returns a promise
}
return {
getBookingData: getBookingData,
getCommissionData: getCommissionData
};
}
]);
angular.module('alertApp', [
'alertApp.controllers',
'alertApp.services'
]);
angular.module('alertApp.services', []).
factory('alertAPIservice', function($http) {
var alertAPI = {};
alertAPI.getAlerts = function() {
return $http({
method: 'JSONP',
url: 'http://localhost:50828/api/alert'
});
}
return alertAPI;
});
angular.module('alertApp.controllers', [])
.controller('mainController', function($scope, alertAPIservice) {
$scope.message = 'Hello Mid-World!';
$scope.alertsList = [];
alertAPIservice.getAlerts().success(function (response) {
$scope.alertsList = response;
});
});
My app runs fine without errors and I can see the $scope.message displayed on the page. In fiddler I can see that my api call returns a 200 message, but the success function is never called. What have I done wrong
UPDATE
I Changed to:
alertAPIservice.getAlerts().then(function successCallback(response) {
$scope.alertsList = response;
}, function errorCallback(response) {
console.log("turd");
});
And although I receieve a 200 in fiddler, the error callback is called. The response is from web api and is of type Ok();
You need to use the name of the callback as "JSON_CALLBACK".
Please refer your updated code as below -
angular.module('alertApp', ['alertApp.controllers','alertApp.services']);
angular.module('alertApp.services', []).factory('alertAPIservice', function($http) {
var alertAPI = {};
alertAPI.getAlerts = function() {
return $http.jsonp('https://angularjs.org/greet.php?name=StackOverflow&callback=JSON_CALLBACK');
//use &callback=JSON_CALLBACK' in url
}
return alertAPI;
});
angular.module('alertApp.controllers', [])
.controller('mainController', function($scope, alertAPIservice) {
$scope.message = 'Hello Mid-World!';
$scope.alertsList = "loading data";
alertAPIservice.getAlerts().then(function (response) {
$scope.alertsList = response.data;
},function(error,a,b){
$scope.alertsList = error;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="alertApp">
<div ng-controller="mainController">
{{message}}
<div>
<pre>{{alertsList|json}}</pre>
</div>
</div>
</body>
you can refer jsonp documentation here.
Hope this helps you!
Try this one ('then' instead of 'success' ):
alertAPIservice.getAlerts().then(function (response) {
$scope.alertsList = response;
});