I'm writing an Ionic app to read some data from a web API I created with asp.net MVC4. The Ionic app reads the data just fine when I'm hosting it on my local machine but the angular factory does not return anything when I try to read from the web API when it is published on Azure. Is there any logical reason why this wouldn't work when it is published to Azure?
The json string is the same on both when i visit the local and azure site.
[{"ID":1,"Name":"Fireworks","Time":"2015-11-30T21:00:00","Comments":"Be there by 8:00"},
{"ID":2,"Name":"Haircut","Time":"2015-11-30T21:00:00","Comments":"Be there by 8:00"}]
Here is the code for my angular factory
.factory('EventsFactory', ['$http', function($http) {
return $http.get('webAPI link here')
.success(function(data) {
return data;
})
.error(function(err) {
return err;
});
}])
Here is the code for my angular controller
.controller('EventCtrl', ['$scope', 'EventsFactory', function($scope, EventsFactory) {
EventsFactory.success(function(data){
$scope.activities = data;
});
}])
Here is the code for my view
<div class="list card" ng-controller="EventCtrl">
<div class="item item-divider">Upcoming Events</div>
<div class="item item-body" ng-repeat="activity in activities">
<div>{{activity.Name}}</div>
</div>
</div>
Why you add success method with Controller and factory. add success method only controller. like
.factory('EventsFactory', ['$http', function($http) {
return $http.get('webAPI link here');
}])
In your controller, you need to use then
EventsFactory().then(function(data){
$scope.activites = data;
})
Related
I have an application with a parent controller called DashboardCtrl, and multiple child controllers (DashboardBuyerCtrl, DashboardSellerCtrl...)
I'd like to be able to share the results of an HTTP request between the different controllers.
At the moment, I'm executing my HTTP request in every controller, but I think that this is not ideal performance wise.
I've read that I should use service, but I'm stuck here.
can anyone help?
Thanks
Using services is, in general, a good practice because helps you to organize and share the code across your application, I've created a small app to showcase how services could be created and reused in controllers:
var app = angular.module('testApp', []);
app.controller('ctrlA', function($scope, getIp) {
getIp().then(function(resp) {
$scope.data = resp.data.origin;
});
});
app.controller('ctrlB', function($scope, getIp) {
getIp().then(function(resp) {
$scope.data = resp.data.origin;
});
});
app.service('getIp', function($http) {
return function() {
return $http.get('https://httpbin.org/ip');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="testApp">
<div ng-controller="ctrlA">
First controller
<p>IP: {{data}}</p>
</div>
<div ng-controller="ctrlB">
Second controller
<p>IP: {{data}}</p>
</div>
</div>
Regarding performance, I'd suggest using caching option if content is not being updated frequently(or not updated at all), like so:
$http({
url: '...',
method: 'GET',
cache: true
});
This will save request's response for future use.
You can read more about services in the official documentation.
I'm making a simple CRUD application to CRUD products. A product has an ID, a Name and a Price. I have built an ASP.NET Web API to store these products and I was trying to call this API in an AngularJS SPA. I have built a module and corresponding component to fetch all products from the API and to render them in a view (listProducts).
I'm not sure how I should be putting the API address in the $http.get() method. My API address is: localhost:58875/api/products. My code:
list-products.module.js
angular.module('listProducts', []);
list-products.component.js
angular.
module('listProducts').
component('listProducts', {
templateUrl: 'app/products/list-products/list-products.html',
controller: ['$http',
function listProductsController($http) {
var self = this;
$http.get('http://localhost:58875/api/products').then(function(response) {
self.products = response.data;
});
}
]
});
I'm also having trouble in my view, because angular is telling me that it doesn't recognize my controller and I can't figure out why.
list-products.html
<div class="container" ng-controller="listProductsController">
<h2>Products</h2>
<hr>
<div ng-repeat="p in products">
<li>{{p.ID}}</li>
<li>{{p.Name}}</li>
<li>{{p.Price}}</li>
</div>
</div>
I am trying to run an $http function when my AngularJS application first loads.
This $http function needs to finish before any of the controllers in my application could properly function. How would I go about doing this? This sounds like a promise, but it sounds like I would be creating a promise in each controller...
I currently have the function that I want to run first like this:
app.run(function() {
$http.get('link').success(function(data) {
// success function. The data that I get from this HTTP call will be saved to a service.
}).error(function(error) {
});
});
However, sometimes the controller will load before the http call finishes.
The problem
Angular is not dynamic, you cannot add controller dynamically neither factory, etc. Also you cannot defer controller bootstrap, angular loads everything together, and it's quite disadvantage (will be fixed in Angular 2)
The cure
But javascript itself has very important feature - closure, which works anywhere, anytime.
And angular has some internal services that can be injected outside of angular ecosystem, even into browser console. Those services injected as shown below. We technically could use anything else (jQuery.ajax, window.fetch, or even with XMLHttpRequest), but let's stick with total angular solution
var $http_injected = angular.injector(["ng"]).get("$http");
The act
First of all, we defer whole angular app bootstrap, inject http service. Then you make your needed request, receive data and then closure get's to work, we pass received data into some service, or we could also assign in to some angular.constant or angular.value but let's just make demo with angular.service, so when your service has data, bootstrap whole app, so that all controllers get initialized with your needed data
Basically that kind of tasks solved like this
<body>
<div ng-controller="Controller1">
<b>Controller1</b>
{{text}}
{{setting.data.name}}
</div>
<hr>
<div ng-controller="Controller2">
<b>Controller2</b>
{{text}}
{{setting.data.name}}
</div>
<script>
//define preloader
var $http_injected = angular.injector(["ng"]).get("$http");
$http_injected.get('http://jsonplaceholder.typicode.com/users/1').then(function(successResponse) {
//define app
angular.module('app', []);
//define test controllers
//note, usually we see 'controller1 loaded' text before 'settings applied', because controller initialized with this data, but in this demo, we will not see 'controller1 loaded' text, as we use closure to assign data, so it's instantly changed
angular.module('app').controller('Controller1', function($scope, AppSetting) {
$scope.text = 'controller1 loaded';
$scope.setting = AppSetting.setting;
$scope.$watch('setting', function(e1 ,e2){
$scope.text = 'settings applied'
});
});
angular.module('app').controller('Controller2', function($scope, AppSetting) {
$scope.text = 'controller2 loaded';
$scope.setting = AppSetting.setting;
$scope.$watch('setting', function(e1 ,e2){
$scope.text = 'settings applied'
});
});
//define test services, note we assign it here, it's possible
//because of javascript awesomeness (closure)
angular.module('app').service('AppSetting', function() {
this.setting = successResponse;
});
//bootstrap app, we cannot use ng-app, as it loads app instantly
//but we bootstrap it manually when you settings come
angular.bootstrap(document.body, ['app']);
});
</script>
</body>
Plunker demo
You can do this when you configure your routes
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
controller: 'MainCtrl',
templateUrl: 'main.html',
resolve: {
data: ['$http',
function($http)
{
return $http.get('/api/data').then(
function success(response) { return response.data.rows[0]; },
function error(reason) { return false; }
);
}
]
}
});
}]);
Similar question:
AngularJS - routeProvider resolve calling a service method
AngularJS: $routeProvider when resolve $http returns response obj instead of my obj
Heres a plunkr I found using a service, which is what I would recommend.
http://plnkr.co/edit/XKGC1h?p=info
I have a basic app, that fetches some data through the $http service, however it doesnt render the data correct in the template, when the template is served from the template cache. My code looks like this:
angular.module('app', [])
api service:
.factory('api', function($http, $q) {
return {
getCars: function() {
return $http.get('api/cars');
}
};
})
the controller using the service:
.controller('carsCtrl', function($scope, api) {
api.getCars().success(function(data) {
$scope.cars = data;
});
})
the route setup:
.config(function($routeProvider) {
$routeProvider.when('/cars', {
templateUrl: 'cars.html',
controller: 'carsCtrl'
});
});
and the template cars.html
<div ng-repeat="car in cars">
{{ car }}
</div>
this works the first time the browser hits /cars, however, if I push the back on forward button in the browser to hit the url a second time without a page reload, the {{car}} is not being rendered. If the cars.html is put in the templateCache like this:
angular.module('app').run(function($templateCache) {
$templateCache.put('cars.html', '<div ng-repeat="car in cars">{{ car }}</div>');
});
the {{car}} binding is not rendered either.
I suspect this has something to do with Angular not unwrapping promises in templates anymore, but not totally sure. Does anyone know what I am doing wrong and how to write this code correctly?
Well, I saw some syntax errors in your code (maybe you didn't copy the code but typed it manually for SO not sure). Also you returned deferred instead of deferred.promise. What you trying to achieve works just fine:
Plnkr Example
Im trying to get my Google Plus Page's posts, activity feed via JSON to display on my website.
Im using AngularJS to do that. Im not sure what im doing wrong.
When I run this, in the page it doesnt show anything.
Also, I get CONSOLE error: Uncaught SyntaxError: Unexpected token : public:2
'use strict';
var app = angular.module('teamamr', ['teamamr.controller']);
var controllers = angular.module('teamamr.controller', []);
controllers.controller('googlePosts', function ($scope, $http) {
$http.jsonp('https://www.googleapis.com/plus/v1/people/117069052843337874560/activities/public?maxResults=10&key=MYKEY')
.then(function (data) {
$scope.items = data;
console.log(data);
});
});
HTML PART: while html tag has ng-app="teamamr"
<div class="w-row" ng-controller="googlePosts">
<div class="w-col w-col-4 services" ng-repeat="post in items">
<h3>{{post.title}}</h3>
<p>read more</p>
</div>
</div>
Could you try to replace your JSONP call by this one
$http.jsonp('https://www.googleapis.com/plus/v1/people/117069052843337874560/activities/public?callback=JSON_CALLBACK&maxResults=10&key=MYKEY').success(function(data, status, headers, config) {
console.log(data);
$scope.items = data.items;
});
Please note that I have added a &callback=JSON_CALLBACK in the url and replace then(...) by success(...)