2

Previously I was passing url by some services in angular js. Now I want to pass url to $resource from controller as a parameter.

I have tried to pass url to resource from controller but it throwing error that url object not found.

Following is my current factory code:

angular.module('Services').factory('PatientsService', ['$resource', 'Service', '$http',

    function(Resource, Service, Http) {

        return {
            testGetPatients : Resource(Service.getPatientsCustomRefURL(), {}, {
                query : {
                    method : 'GET',
                    isArray : false
                }
            })
        };                                                                                                                                                                                                                                                                                                                                                                                                      
}]);

In above code I am sending url parameter from Service.getPatientCUstomRefURL

Actual call to $resource is shown below:

PatientsService.getPatientsRef.query(function(refResponse) { 
//TODO for response
});

Now I want to pass Parameter something like this:

PatientsService.getPatientsRef.query("/patient/list",function(refResponse) {
//TODO for response
 });

What changes should I make in my PatientsService factory so that it will support passing url as parameter.

Here is code which will create url for $resource Services code

angular.module('Services', ['ngResource']).factory('Service', ['$resource', '$location', '$rootScope',
                                                               function($resource, $location, $rootScope) {
    return {
        getPatientsCustomRefURL: function() {
            return '/patient/list';
        }
    };
}
]);

Note

I have so many methods in PatientService, so i dont want to add extra function in patientService for each $resource, which will pass url as parameter like

angular.module('Services').factory('PatientsService', ['$resource', 'Service', '$http',
        function(Resource, Service, Http) {

            return {
                testGetPatients : function(url){
                 return Resource(url, {}, {
                    query : {
                        method : 'GET',
                        isArray : false
                    }
                })
            }
            };                                                                                                                                                                                                                                                                                                                                                                                                      
       }]);
Darshan Jain
  • 316
  • 2
  • 9
  • what is the value returned by `Service.getPatientsCustomRefURL()` ? can you do a `console.log(Service.getPatientsCustomRefURL())` before return and check the value – Fraction Mar 29 '19 at 15:23
  • Service.getPatientsCustomRefURL() will return an string url – Darshan Jain Mar 29 '19 at 15:32
  • can you check with `console.log` ? maybe it return a promise or undefined – Fraction Mar 29 '19 at 15:34
  • @Fraction i have updated my question by adding Service.getPatientsCustomRefURL() code. and thanks for quick reply – Darshan Jain Mar 29 '19 at 15:44
  • @Fraction oops, i copied on scenario to show a demo from whole project. you are correct it should be getPatientCUstomRefURL in service. updating the question again. now did you find perfect scenario? Thanks for replying – Darshan Jain Mar 29 '19 at 15:57
  • Why are you changing the "query" verb to get a single object? The standard way to get a single object is to use the "get" verb. Changing the "query" verb will confuse people trying to maintain your code. – georgeawg Mar 29 '19 at 16:06
  • @Fraction, this is we used in the context context of api call which consist parameters mapped to 'sql where' clause in backend. – Darshan Jain Mar 29 '19 at 16:09
  • @DarshanJain I can't reproduce the error, you can check this working example: https://codesandbox.io/s/j4kzmwx3mv – Fraction Mar 30 '19 at 17:58
  • Hi @Fraction, Actually i am finding alternate solution for code that you have mentioned. actually i am having very large code base, warping up $resource with function and passing url as parameter will take lots of refactoring of existing code. I am looking for alternate solution for sending url as parameter to $resource in factory. Thanks for reply. – Darshan Jain Mar 31 '19 at 05:22

2 Answers2

0

Now I want to pass Parameter something like this:

PatientsService.getPatientsRef.query("/patient/list",function(refResponse) {
//TODO for response
 });

For an API call like that, it would be easier to use the $http service:

$http.get("/patient/list").then(function(response) {
    var refResponse = response.data;
    //TODO for response
});

The standard way to vary the url with the $resource service is to define parameters in the url template:

var service = $resource("/api/:slug/list", {slug: patient}, {
    getByID: {
        url: "/api/:slug/:id",
        method: "GET",
        isArray: false,
   }
);

Examples:

$scope.patients = service.query(); //returns array from
//  api/patient/list 

$scope.doctors = service.query({slug: doctor}); //returns array from
//  api/doctor/list

$scope.patientRecord = service.getById({id: 1234}); //returns object from
//  api/patient/1234

$scope.patientRecord = service.get({id:1234}); //returns object from
//  api/patient/list?id=1234

A parameterized URL template uses parameters prefixed by : as in /user/:username. If you are using a URL with a port number (e.g. http://example.com:8080/api), it will be respected.

Each key value in the parameter object is first bound to url template if present and then any excess keys are appended to the url search query after the ?.

It is important to realize that invoking a $resource object method immediately returns an empty reference (object or array depending on isArray). Once the data is returned from the server the existing reference is populated with the actual data. This is a useful trick since usually the resource is assigned to a model which is then rendered by the view.

For more information, see AngularJS $resource API reference - Arguments

georgeawg
  • 48,608
  • 13
  • 72
  • 95
  • can there is any way to change existent $resource, because i have used $resource at so many times, your solution required change in all code. Thanks for reply. – Darshan Jain Mar 29 '19 at 16:42
  • Under the hood, the $resource service uses the $http service. The $resource factory is designed to facilitate interaction with [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources. If your server-side data API is not RESTful, it is better to access it with the $http service. I personally don't like the "return empty object, populate later" strategy. I prefer services that return promises. – georgeawg Mar 29 '19 at 18:04
0

for above problem scenario you can wrap your existing $resource in some function and pass url to that function.

angular.module('Services').factory('PatientsService', ['$resource', 'Service', '$http',
        function(Resource, Service, Http) {

            return {
                testGetPatients : function(url){
                 return Resource(url, {}, {
                    query : {
                        method : 'GET',
                        isArray : false
                    }
                })
            }
            };                                                                                                                                                                                                                                                                                                                                                                                                      
       }]);

that make sense .

Pushpak
  • 77
  • 10