I am trying to let UI development proceed without needing to be coupled to a backend. My the normal REST api is being built like:
a.factory('Sample', ['$resource',
function($resource){
return $resource(baseUrl() + '/sample/:id', {}, {
query: {method:'GET', params:{id:''}, isArray:true, cache:false},
update: { method:'PUT' },
remove: { method:'DELETE'}
});
}]);
This is fine when there is an actual backend. However, for development purposes (NOT Testing), canned data from a file is desired. This can be achieved like:
['$scope', '$http',
function($scope, $http) {
$http.get('data/sampleList.json').success(function(data) {
$scope.sampleData = data;
});
}]
Obviously, I'm no expert here, but I am wondering if there is an easy way to combine these two approaches such that the $resource REST instance can return (for GET requests anyway), canned data from a file?
Why didn't you say this was such a newb question or that you never RTFM? Oh wait, this is my own question! So, sorry folks, didn't realize this was quite so trivial - there is a 'URL' parameter available on every such method. While this will only work for Mockups or UI dev before the backend is done, for the above, all I needed to do was:
a.factory('Sample', ['$resource',
function($resource){
return $resource(baseUrl() + '/sample/:id', {}, {
query: {url: 'data/sampleList.json', method:'GET', params:{id:''}, isArray:true, cache:false},
update: { method:'PUT' },
remove: { method:'DELETE'}
});
}]);
qed
Related
I have to load a JSON file from another server (where I don't have control). After some hours researching found that JSONP is the dirty hack that answers mine pleads.
I am using nodejs, serving the site on localhost:3000 using gulp.
Loading the JSON from localhost:8000
I was able to get an example working, from an URL I do not need (found it randomly on the Internet), using the same code that I had not working with my URL.
That makes me wonder if I am trying to read the file like something it is not? As far as I could research it shouldn't be needed to parse a JSON into JSONP. Am I on the right track?
Underneath, the code which I was talking about:
(function () {
'use strict';
angular
.module('qwe.asd')
.controller('UsersController', UsersController);
/** #ngInject */
function UsersController($http, $log, $sce) {
var vm = this;
var trustedUsersAPI = "http://localhost:8000/users?callback=JSON_CALLBACK";
$sce.trustAsResourceUrl(trustedUsersAPI);
$http.jsonp(trustedUsersAPI, {
'callback': 'JSON_CALLBACK'
})
.success(function (data) {
$log.log("request 1 - OK");
$log.log(data);
vm.users = data;
})
.error(function () {
$log.log("request 1 - KO");
});
var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=JSON_CALLBACK";
$sce.trustAsResourceUrl(url);
$http.jsonp(url)
.success(function (data) {
$log.log("request 2 - OK");
$log.log(data);
})
.error(function () {
$log.log("request 2 - KO");
});
}
})();
And the logs generated...
angular.js:13424 request 1 - KO
angular.js:13424 request 2 - OK
angular.js:13424 Object {found: 12, posts: Array[12]}
And finally, the JSON files I am (mis)reading:
The one I need but I can't have
[{"id":0,"firstname":"front","lastname":"end","email":"frontend#example.com"},{"id":1,"firstname":"back","lastname":"end","email":"backend#example.com"},{"id":2,"firstname":"john","lastname":"doe","email":"johndoe#example.com"},{"id":3,"firstname":"dev","lastname":"eloper","email":"developer#example.com"},{"id":4,"firstname":"ad","lastname":"min","email":"admin#example.com"}]
And the one I don't need but works fine
{"found":12,"posts":[{"ID":XX,"site_ID":XXXX,"author":XXXX(..POSTS DATA WITH NO VALUE HERE..)}]}
P.S. I am really green here, I am on angular since this morning!
For those who come after me, I was following the wrong track. Thanks to the commenters I learnt that JSONP has to be supported on the server (just like CORS does).
I am just playing around with angular JS and wiring it up to some restful web services I have implemented. I have moved onto using the $resource module provided by angular and have a simple question (I hope). In my code below I am making a request to a spring boot micro service I have written and am wanting to know the best way of accessing the URL.
So is there another way of calling the resource that is cross origin rather than having to write the line below. Is there something like /customer/greeting I could use but then how would I specify the different port as my angular app resides on localhost:8000?
http://localhost\:9001/customer/greeting //this is a spring boot application
My full code for the service.js is below this resides on localhost:8000 and is a node JS server.
'use strict';
/* Services */
var phonecatServices = angular.module('phonecatServices', ['ngResource']);
phonecatServices.factory('Phone', ['$resource',
function($resource) {
return {
pDetail: $resource('phones/:phoneId.json', {}, {
query: {method: 'GET', params: {phoneId: 'phones'}, isArray: true}
}),
cDetail: $resource('http://localhost\:9001/customer/greeting', {}, {
query: {method: 'GET'}
})
};
}]);
When people normally implement do they have lots of http://balh blah when it goes cross origin? Is there a pattern that can be applied here?
Thanks in advance.
You can do this way:
Make function
var getCrossOriginUrl=function(portNo){
var crossOriginPath="http://localhost\:"
return crossOriginPath+portNo+"/";
}
So now you can call this way:
$resource(getCrossOriginUrl(9001)+'customer/greeting',{}, {
query: {method: 'GET'}
})
In my angular application I have the following controller (I have deleted some methods due privacy policy):
.controller('ArticleCtrl', ['$http', '$scope', '$location', '$localStorage', '$q', '$templateCache', 'authService',
'uploaderService', 'settings',
function($http, $scope, $location, $localStorage, $q, $templateCache, authService, uploaderService, settings) {
$scope.isAuth = authService.checkAuthStatus() || false;
if ($scope.isAuth == false) {
$location.path('/signin');
}
$scope.username = $localStorage.authStatus.userName;
$scope.getCompany = function(id) {
$http.get(settings.apiBaseUri + '/app/' + id, {
headers: {
'Content-Type': 'application/json',
'Cache-Control': 'no-cache'
}
})
.success(function(response) {
$scope.company = response;
$scope.company.Email = $scope.username;
})
.error(function(data, status, headers, config) {
console.log('operation failed, status: ' + data);
$location.path('/signin');
});
$scope.$apply();
};
if ($scope.isAuth == true) {
$scope.company = $localStorage.selectedCompany;
$templateCache.removeAll();
$scope.getCompany($localStorage.selectedCompany.Id);
}
}
]);
I have spend a lot of time, but still I don't understand why does only this contoller gets cached (other controllers were made via copy-paste).
But when this method is called for the first time: all is ok, in debugger I see that it goes to server via GET method, but when I refresh the page, and then go again to this controller - in Firefox and IE I see that there are no new requests to the server. But why? Only when I refresh the page with Ctrl + F5 all is ok. But users will do not do that, I need working application...
Maybe somebody knows how to fix this issue? How to disable angularjs view and controller caching?
UPD:
I see that after update my localstorage isn't changing in IE and Firefox. Why?
Sorry, I do not directly answer the question, but what is coming seems important.
I, and other people, strongly discourage to use ngStorage right now.
Indeed, ngStorage, seems very, very handy. You just directly change the object, and voilĂ , everything works. I used this a bit, this was cool :)
But, sadly, when you try to make an advanced use, or when you take a look at the source code, you see there are several problems. This awesome "immediate localStorage object modification" is made watching stuff with the $rootScope. That's not a good idea for performance. Moreover, you probably saw that some GitHub issues are stating similar sync problems, like you do. Also, be aware that the project is now completely unmaintained. Use such a library in production is a bad idea.
So, you may give a try to another solution to make the link with the localStorage, such as Angular Locker, becoming more and more used. This will lead to some code refactoring, but you future self will thank you to not have used a problematic library.
First be sure that id parameter is correct. And second be sure that the request headers has no-cache. Probably you have request interceptor and this interceptor override the headers. Track this request in firebug for firefox.
If you see the 'no-cache' values check the server out. Maybe server could cache this.
I've been hunting for a few hours now and can't seem to find any information specific to my setup so here goes.
I'm using the MEAN stack and wanting to use the Twitter API in my angular app. I have all the required keys and trigger a twitter api authentication on the server side using Node, then pass the token I get in response to my angular pages. I was hoping to be able to use this token to make requests to the api from an angular service. The request I'm trying to get working the moment is to fetch a given user's profile object. I've attached my service method below. The error I get when I run it is a 405 method no allowed, no access-control-allow-origin header is present.
angular.module('tms.system').factory('Twitter', ['$log', '$q', '$http', '$window', 'twitter', 'Global', function($log, $q, $http, $window, twitter, Global) {
return {
findProfile: function(handle) {
var deferred = $q.defer();
var config = {
timeout:3000,
headers: {
'Authorization': 'Bearer ' + Global.twitterToken,
'X-Testing' : 'testing'
}
};
$http.get('https://api.twitter.com/1.1/users/show.json?screen_name=' + handle, config).
success(function(data) {
$log.info(data);
deferred.resolve(data);
}).
error(function(status) {
$log.error(status);
});
return deferred.promise;
}
};
}]);
Just for future reference, as stated in the comments of maurycy's answer {and being myself trying to get tweets just from Angular without succes}, the best approach for this would be to get them from some backend.
I believe you should use $http.jsonp with a JSON_CALLBACK to get it to work, it's not going to happen with $http.get for sure
I am trying to set some customer headers in a service factory. Here is the code:
angular.module('clinicalApp').factory('encounterService', function ($resource) {
var EncounterService = $resource('http://localhost:port/v1/providers/:providerId', {providerId:'#id', port: ':8280'}, {
search: {
method: 'GET',
isArray: true,
headers: {
'RemoteUser': 'billybob'
}
}
});
return EncounterService;
});
Here is the code that calls the service.
angular.module('clinicalApp').controller('MainCtrl', function ($scope, encounterService) {
encounterService.search({
limit: 2000,
organizationId : '11110000'
});
});
When I use this resource and everything works fine, but the header is not set on the ajax call, so I get a 401 in return. What else do I have to do to set the headers? Thanks for the help.
I am sure the other answers I received work, but I did not want to use $http, I wanted to use $resource. To use resource with custom headers, I had to upgrade my Angular version. I did not look into the source code to find the reason why, and I don't know what version this functionality changed. Right now I am using v1.2.0-rc.2 and everything just worked. It took a few changed in the app config, namely I had to name ngRoute as a dependency to make the version work, but then I was able to use $resource like we are supposed to do.
Don't use run(), use config() with $httpProvider:
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.headers.common = {
'RemoteUser': 'billybob'
};
}])
clinicalApp.run(function($http) {
$http.defaults.headers.common["Content-Type"] = "application/json, charset=UTF-8";
});