11

I have created an angular service to talk back to a simple REST server made in PHP. I can see that I am able to get a single record, list of all records, and add new records, however, after adding new records I am having an issue with getting the correct response from the server to be able to act upon it.

I know it's working because the new records are getting added, however, I wish to put notifications for users if for whatever reason the request does not work, and so forth...

This is the service:

angular.module('adminApp.services', ['ngResource'])

    .factory('Settings', function($resource) {

        return $resource('rest/setting/:id', {id: '@id'}, {
            'query' : { method: 'GET', params: {}, format: 'json', isArray: true },
            'save'  : { method: 'POST', params: {}, format: 'json', isArray: true },
            'get'   : { method: 'GET', params: {}, format: 'json', isArray: false },
            'update': { method: 'PUT', params: {id: '@id'}, format: 'json', isArray: true },
            'delete': { method: 'DELETE', params: {id: '@id'}, format: 'json', isArray: false }
    });

});

As part of the controller, I have the following:

$scope.save = function() {
    var result = Settings.save({}, $scope.settings);

    console.log(result);

    // Here I would like to send the result to the dialog
    // to determine wether or not the request was successful
    // dialog.close(result);
};

The Network response from the HTTP request, as seen via the javascript console returns 'true' which comes back from the server, however, the console.log(result) returns an array of the characters in 'true' -- I had guessed this is because of the isArray : true option in 'save' which is necessary because the params get sent to the server as an array though:

[$promise: Object, $resolved: false]
    0: "t",
    1: "r",
    2: "u",
    3: "e",
    $promise: Object,

    // I tried passing result.$resolved to the dialog,
    // but if yousee above it resolves to false up top first
    $resolved: true,
    length: 4,
    __proto__: Array[0]

I know the HTTP response is a json value of true, if I could hook into that it would be easy (I come from a jQuery background, maybe I'm doing it wrong, I have made it a point to remove jQuery completely from this project as to not allow it to inhibit my learning).

I guess the question is, how do I actually get that response from the server onto a JS variable I can actually work with?

Edit: Updated

I changed my service to:

angular.module('adminApp.services', ['ngResource'])
    .factory('Settings', function($http, $resource, $log) {
        return $resource('rest/setting/:id', {id: '@id'}, {
            save   : {
            method: 'POST',
            params: {},
            format: 'json',
            isArray: true,
            transformResponse: [function(data, headersGetter) {
                $log.info(data); // returns true
                return { response: data };
            }].concat($http.defaults.transformResponse)
        },
        update : { method: 'PUT', params: {id: '@id'}, format: 'json', isArray: true },
        delete : { method: 'DELETE', params: {id: '@id'}, format: 'json', isArray: false }
    });

});

And the call to:

$scope.save = function() {
    $scope.results = Settings.save({}, $scope.settings);
    console.log($scope.results); // Still returns the response with $promise
    //dialog.close(true);
};

But I'm still not getting true as the response

7
  • I hope I understand the problem. Try adding two callbacks to your Settings.save call. They are the success and failure callbacks respectively. See here: docs.angularjs.org/api/ngResource.$resource. I suppose you can show the error code from your second callback. Commented Jul 2, 2013 at 4:48
  • I'm pretty sure you don't need isArray for the sent data to be an array, it just modifies the return value interpretation docs.angularjs.org/api/ngResource.$resource Commented Jul 2, 2013 at 4:48
  • @shaunhusain When I had isArray : false I would get an error notifying that the push variable was not available, some googling revealed that this was fixed by adding isArray: true to the call. Commented Jul 2, 2013 at 4:49
  • @akonsu I am not certain how to add the callback, would I add it in the service? If so, where do I add it? Would it just be callback: function() as an added parameter of save? Commented Jul 2, 2013 at 4:50
  • I mean like that: Settings.save({}, $scope.settings, function () {...}, function (error) {...}) Commented Jul 2, 2013 at 4:52

2 Answers 2

13

See this fiddle: http://jsfiddle.net/moderndegree/Kn3Tc/

angular.module('myApp', ['ngResource']).
factory('myService', function($http, $resource, $log){
    return $resource('/', {}, {
        get: {
            method: 'GET',
            transformRequest: [function(data, headersGetter){
                // you can examine the raw request in here
                $log.info(data);
                $log.info(headersGetter());
            }].concat($http.defaults.transformRequest),
            transformResponse: [function (data, headersGetter) {
                // you can examine the raw response in here
                $log.info(data);
                $log.info(headersGetter());
                return {tada:"Check your console"};
            }].concat($http.defaults.transformResponse)
        }
    });
}).
controller('myController', function(myService, $scope, $resource, $http, $log) {
    $scope.results = myService.get();
});

To globally augment or override the default transforms, modify the $httpProvider.defaults.transformRequest and $httpProvider.defaults.transformResponse properties.

read more here: http://docs.angularjs.org/api/ng.$http

Sign up to request clarification or add additional context in comments.

8 Comments

Ah this is very cool, so this allows for something like "interceptors" on the client side?
Correct. If you wanted a global interceptor, you can add it to the $httpProvider in your app config.
I experimented with your fiddle and tried to amend my answer, but still having issues. May you please take a look and comment? I must be doing something wrong as I'm not getting the transformed response at the controller end.
@francisco.preller it will always return a promise response. why do you expect otherwise? it is an asynchronous operation. transforResponse et al are just callbacks and you will get your raw data in these callbacks.
@akonsu Perhaps I am mistaken, but the fiddle above manages to transform the response to an object with the 'tada' key and a string for a value and then fetch that with his controller. I am trying to do the same, and I am not getting the same results as he gets in his fiddle.
|
0

Hi i know its too late but may be helpful for others, The reason behind conversion of response to array is, angular-resource expects "data" property in response and after that it iterate over each items inside the "data" but if you sends an string inside the data property from server like this

response = {
    data: true
    }

then Angular-resource iterate over the "data" Object and makes an array of data so, the correct way is to send response is like this

response = {
    data: {users: users} // Or any other property but not directly data
    }

Thanks

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.