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
};
}
]);
Related
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/
I am new to this field so need help.I have to post data to API but i am unable to do this.Please help me and let me now the process.
API is: http://trendytoday.in/ers/api/DeviceAlarms
And JSOn format in which i have to send data is:
{
"ers": {
"agency_device_id": "1"
}
}
AngularJS provides the $http service, which has a method most. This can be used like:
var app = angular.module("app", []);
app.controller("HttpGetController", function($scope, $http) {
$scope.SendData = function() {
var data = {
"ers": {
"agency_device_id": "1"
}
}
$http.post('http://trendytoday.in/ers/api/DeviceAlarms', data)
.then(function(res) {
console.log(res);
}, function(err) {
console.error(err);
})
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="HttpGetController">
<button ng-click="SendData()">Submit</button>
<hr /> {{ PostDataResponse }}
</div>
This should be called from a controller or a service, and whichever you choose should have the $http service included as a dependency.
.controller('AppCtrl', function($scope, $http) {
$scope.ers = {
'agency_device_id' : ''
};
$scope.submit = function(){
var link = 'http://trendytoday.in/ers/api/DeviceAlarms';
$http.post(link, {ers: $scope.ers},{headers: {'Content-Type': 'application/json'} }).then(function (res){
$scope.mssg = res.data.ers.resMessage;
$scope.resp = res.data.ers.response;
I am calling a json in controller using service but I am receiving an error saying "TypeError: Cannot read property 'then' of undefined". I tried existing answers but couldn't get it to work.
Controller:
app.controller("myController",["$scope","MyService","$http", function($scope,MyService,$http){
$scope.hi = "hello";
MyService.getMyData().then(function(response){
console.log(response);
});
}]);
Service:
app.service("MyService", ["$http", function($http) {
this.getMyData = function() {
return
$http({
method: 'GET',
url: 'myList.json',
headers: {
'Content-Type': 'application/json'
}
}).then(function successCallback(response) {
console.log(response);
return response;
}, function errorCallback(response) {
console.log(error);
return response;
});
};
}]);
Thank you.
Currently you had just return(on first line) thereafter on next line you returned $http promise. Basically you have return alone it returns nothing/undefined (this is how javascript works) & next statements are getting ignored from this.getMyData function.
You have to have return & $http({ promise to be together in one line, otherwise return will return empty statement.
this.getMyData = function() {
//`return` & `$http` promise should be on same line, otherwise undefined would get return
return $http({
method: 'GET',
url: 'myList.json',
headers: {
'Content-Type': 'application/json'
}
}).then(function successCallback(response) {
console.log(response);
return response;
}, function errorCallback(response) {
console.log(error);
return response;
});
};
#pankajparker is absolutely correct.
Implemented a codepen for kicks and adjusted to use Angular 1.5's components. Here's the link:
http://codepen.io/Lethargicgeek/pen/YWryoE
(function() {
angular.module("myApp", []);
angular.module("myApp").component('myCmp', {
controller: ctrlFn,
templateUrl: "myCmp.tpl.html"
});
ctrlFn.$inject = ["myService"];
function ctrlFn(myService) {
var $ctrl = this;
// BINDINGS
$ctrl.hi = "hello";
$ctrl.getData = getData;
$ctrl.data = null;
$ctrl.myService = myService; // Binding so that we can easily see results
// END BINDINGS
// FUNCTION
function getData() {
var returnedPrms = myService.getMyData();
returnedPrms.then(function(response) {
$ctrl.data = response;
});
}
// END FUNCTIONS
}
angular.module("myApp").service("myService", svcFn);
svcFn.$inject = ["$http"];
function svcFn($http) {
var svc = this;
//BINDINGS
svc.getMyData = getMyData;
//END BINDINGS
function getMyData() {
var firstPrms = $http.get("http://codepen.io/anon/pen/LVEwdw.js"); // Random bit of json pulled from internets
var secondPrms = firstPrms.then(function success(response) {
svc.successResp = response;
return response;
}, function error(response) {
svc.errorResp = response;
return response;
});
return secondPrms;
}
}
})(); // end iife
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js"></script>
<div ng-app="myApp">
<script type="text/ng-template" id="myCmp.tpl.html">
<div>
<h1>{{$ctrl.hi}}</h1>
<a class="btn btn-primary" ng-click="$ctrl.getData()">
Trigger $Http Call
</a>
<dl class="dl-horizontal">
<dt>$ctrl.data:</dt>
<dd>{{$ctrl.data}}</dd>
<dt>$ctrl.myService.successResp:</dt>
<dd>{{$ctrl.myService.successResp}}</dd>
<dt>ctrl.myService.errorResp:</dt>
<dd>{{ctrl.myService.errorResp}}</dd>
</dl>
</div>
</script>
<my-cmp></my-cmp>
</div>
How can i make the testservice factory return the result from the post request?, or make the app, factory update some $scope details thats within the overallcontroller ?
how can i update information within the overallcontroller from another controller?
app.factory('testservice', ['$http', 'auth', function($http, auth) {
var o = {
posts : []
};
o.test = function() {
return $http.post('/poster', null, {
headers: {Authorization: 'Bearer '+auth.getToken()}
}).success(function(data){
console.log(Data);
});
};
return o;
}]);
app.controller('overallController', ['$scope', 'posts', 'testservice', 'auth','$interval',
function($scope, posts, testservice, auth, $interval) {
$scope.data = {cash:"12879999",location:"test2",gang:"None","username":"test",
xp: 1290,
health: 100,
wanted: 30,
energy: 90};
var databackground = function() {
console.log("logging...");
var t = testservice.test;
console.log(t);
}
databackground();
$interval(databackground, 30000);
}]);
example html
<div class="main" ng-controller="overallController">
<section class="sides left" style="background:blue; height:100px;">
<ul>
<li ng-hide="isLoggedIn()">Logg inn</li>
</ul>
</section>
<div ng-controller"othercontroller">
// call made from some code here
</div>
</div>
Change your service to
o.test = function() {
return $http.post('/poster', null, {
headers: {Authorization: 'Bearer '+auth.getToken()}
}).then(function(response){
return response.data;
});
};
And in your controller, do call the service, and get the results back in the promise:
testservice.test().then(function(data) {
$scope.data = data;
});
Read more about how to use promises here
You return the promise from your service, you would listen for that to resovle and get hold of your data.
Using $rootScope is heavy handed approach and should be used as a last resort. Services and event are preferable.
var databackground = function() {
console.log("logging...");
testservice.test()
.then(function (res) {
console.log(res.data); //Here is your data
});
}
EDIT: Your service should change slightly also. Firstly .success and .error are deprecated. Use .then and .catch instead.
If you wish to just return data out of your service just do:
o.test = function() {
return $http.post('/poster', null, {
headers: {
Authorization: 'Bearer ' + auth.getToken()
}
});
};
However if you want to transform the data in your service you can but ensure your return it or your controller wont get anything:
o.test = function() {
return $http.post('/poster', null, {
headers: {
Authorization: 'Bearer ' + auth.getToken()
}
})
.then(function (res) {
res.data.test = 'lol';
return res;
})
};
Try referencing $rootScope instead of $scope.
This will allow controllers and factories to interact with each other.
I'm using ng-resource in Angular to access a RESTful API. I created a simple factory to perform this.
.factory('Bookmark', function($resource){
return $resource('http://bookmarks-angular.herokuapp.com/api/bookmarks/:id');
})
And in the controller I used Bookmark.query:
.controller('MainController', function($scope, Category, Bookmark){
$scope.name = 'Carl';
Category.getAll(function(data){
$scope.categories = data.categories;
$scope.currentCategory = data.categories[0];
$scope.bookmarks = Bookmark.query();
});
})
I need to use Bookmark.save and Bookmark.removeand also a token in the Authorization header. Searching this is the approach I have to use:
$resource('url/to/json', {}, {
get: {
method: 'GET',
headers: { 'something': 'anything' }
}
});
But it works just to the get method and I want to use send the token in every $resource methods. I do not want to overwrite all the methods just to send this header. Is there any other solution?
You can create an httpInterceptor, something like this from the angular docs:
$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
return {
'request': function(config) {
// add headers
return config;
}
}
https://docs.angularjs.org/api/ng/service/$http
This might help you in creating interceptor.
http://ramanshankar.blogspot.in/2015/11/angularjs-http-interceptor.html
var app = angular.module('simpleDirective', []);
app.config(['$httpProvider', function($httpProvider){
$httpProvider.interceptors.push('httpInterceptor');
}]);
app.controller("DemoController", ['$rootScope','demoService', function($rootScope, demoService){
$rootScope.message = [];
$rootScope.message.push("In Demo Controller");
demoService.functionOne();
}]);
app.service("demoService", ['$http','$rootScope',function($http, $rootScope){
this.functionOne = function(){
$http.get("temp.html")
.success(function(data){
$rootScope.message.push(data);
})
.error(function(data){
$rootScope.message.push("Demo Service Error: "+data);
});
}
}]);
app.factory("httpInterceptor", function(){
return{
'request': function(config) {
alert("request");
return config;
},
'requestError': function(rejection) {
alert("request error");
return "Request error";
},
'response': function(response) {
alert("response");
return response;
},
'responseError': function(rejection) {
alert("response error");
return "response error";
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="simpleDirective">
<div ng-controller="DemoController">
<h2>AngularJS Interceptor Example</h2>
<div ng-repeat="msg in message">
<div style="padding:5px;background:lightgrey;border:1px solid black;margin-bottom:10px;">{{msg}}</div>
</div>
</div>
</div>