How to Post Json array of objects in AngularJS (using $resource save or via $http service) and How to consume it in Resteasy

895 views Asked by At

At first step, I achieved successfully to save a single user via $resource save in angularjs passed to Resteasy service and eveything works well.

At second step, What I'm trying to do now here is, I want to Post the JSON of array of users (and save in onego via angularjs $resource save this array of objects) to consumer Restful WebService (I use Resteasy).

my json looks like this, right now (an array of users):

 [
        {
            "userid": 1,
            "firstName": "kevin",
            "lastName": "buruk",
            "email": "[email protected]"
        },
        {
            "userid": 2,
            "firstName": "helm",
            "lastName": "krpuk",
            "email": "[email protected]"
        },
        {
            "userid": 3,
            "firstName": "batok",
            "lastName": "kelapa",
            "email": "[email protected]"
        }
    ]

Backend

To achieve my goal I operate few changes on my previous working backend specifically on UserClientServiceImpl like so :

  • 1- By changing the signature of create method (see code below) from final User user signature onto final User[] users signature, to handle array of users instead of a single user.

  • 2- and by adding a loop FOR. to request the already well confirmed
    working create userService

    @Path("/users")

    public class UserClientServiceImpl implements UserClientService {

      @POST
      @Consumes(RestCookieBuilder.JSON_UTF8)
      @Produces(RestCookieBuilder.JSON_UTF8)
      @Override
      public Response create(final User[] users) {<---------Is Signature here is ok? 
    
        Response.ResponseBuilder responseBuilder = Response.ok();
    
        for(User user : users) {
    
          try {
    
            userService.create(user);
    
          }
          catch(Exception e) {
            responseBuilder = Response.status(Response.Status.EXPECTATION_FAILED).entity("{\"error\":\""
                                                                                         + "canceled user :("
                                                                                         + e.getMessage() + ")\"}");
          }
    
    
        }
    
        return responseBuilder.build();
      }
    

    }

Frontend

and changed my UserService in angularjs by adding to save: isArray: true because we are now not working anymore with a single user but instead we are working with an array of users.

In AngularJS, on this service I wrote the below code

 (function () {

        'use strict';

        angular.module('app').factory('UserService', function ($resource){

            return $resource('rest/users/', [],
                {
                    delete: {method: 'DELETE', url: 'rest/users/:id'},
                    save: {method: 'POST',url: 'rest/users',isArray: true},
                    findAll: {method: 'GET', url: 'rest/users'},
                });

        });

    })();

In AngularJS, I made also some changes to the below controller code to post via $ressource to the WebService.

in my controller this time, I created a list of users
and then tried 2 things: 1-My first attempt was to post via $ressource save to the WebService (The code part that is commented in below Listing). 2-My second attempt was to post via $http to the WebService (see below in Listing).

var list = [];

            for(i = 0; i < users.length; i++) {
                var user={};
                user=users[i]['value'];
                list.push(user); 
            }

            /*UserService.save(JSON.stringify(list), function (success) {
              $element.modal('hide');
              close({type: 'success', msg: 'Users created successfully'}, 500);
            }, function (error) {
              alert(" Errorrs for users  !!!!!! "+i);
              createErrorAlert(error);
            });*/

            var liststringifyed=JSON.stringify(list);
            $http.post("rest/users",{users:liststringifyed})
            .success(function (data, status, headers) {
                $scope.ServerResponse = data;
                $element.modal('hide');
                  close({type: 'success', msg: 'Users created successfully'}, 500);
            })
            .error(function (data, status, header, config) {
                $scope.ServerResponse =  data ;

                alert(" Errorrs for users  !!!!!! "+i);

            });

};

as you can see my first attempt see the commented part on code i.e UserService.save(JSON.stringify(list), function (success) it's not working.

on the other hand, in my second attempt I tried also with $http service like you can see but no result either.

Question about Backend:

What's the correct syntax for RestEasy service to consume that json users array ? I mean : on line public Response create(final User[] users) is (final User[] users) as signature would be accepted or should I use other workarounds e.g URI or String AnArray and parse that String like here:

public  create (String AnArray) {
           JSONArray o = new JSONArray(AnArray);

                System.out.println(o.toString());

                return responseBuilder.build();
}

on the other hand on front-end:

-What's the correct syntax in the UserService angularjs to achieve to successfully use save from angularJS $resource service on this case where an array of objects is passed?

is the line JSON.stringify my list is the right thing to do

For $ressource.save

UserService.save(JSON.stringify(list), function (success) {

OR

For $http service

var liststringifyed=JSON.stringify(list);
$http.post("rest/users",{users:liststringifyed}){

N.B: if we can not use save from $resource for that case how to achieve this using $http service ?

Many thanks for your help.

1

There are 1 answers

0
Schwertfisch On

Watch out a late answer but may be helpful for others , verify and check that you Post something like this:

[
        {
            "userid": 1,
            "firstName": "kevin",
            "lastName": "buruk",
            "email": "[email protected]"
        },
        {
            "userid": 2,
            "firstName": "helm",
            "lastName": "krpuk",
            "email": "[email protected]"
        },
        {
            "userid": 3,
            "firstName": "batok",
            "lastName": "kelapa",
            "email": "[email protected]"
        }
]

and not like the following Because by sending or Posting this:

{"users":[
        {
            "userid": 1,
            "firstName": "kevin",
            "lastName": "buruk",
            "email": "[email protected]"
        },
        {
            "userid": 2,
            "firstName": "helm",
            "lastName": "krpuk",
            "email": "[email protected]"
        },
        {
            "userid": 3,
            "firstName": "batok",
            "lastName": "kelapa",
            "email": "[email protected]"
        }
    ]
"}

you are posting an object with a single 'users' named property. you are not posting an array

So my case I were sending an object with a single named property, and when you receive this on backend try to remove the laste two caracters and the substring matching {"users": another thing on the backend your parameter string is a jsonstring so you have to remove all backsalshes to get a valid json.

so to answer this you have to add

dependencies to maven

<dependency>
           <groupId>org.json</groupId>
           <artifactId>json</artifactId>
           <version>20180813</version>
</dependency>
<dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.1</version>
</dependency>

add to

======

import org.json.JSONArray;
import org.json.JSONObject;
import com.google.gson.Gson;


  @POST
  @Consumes(RestCookieBuilder.JSON_UTF8)
  @Produces(RestCookieBuilder.JSON_UTF8)
  @Override
  public Response create(String AnArray) {
    String string2 = "{\"users\":\"";
    int index = AnArray.indexOf("{\"users\":\"");
    if(index == -1) {
      // Not found. What do you want to do?
    }
    else {
      String result = AnArray.substring(0, index) + AnArray.substring(index + string2.length());
      result = result.substring(0, result.length() - 2);
      String jsonFormattedString = result.replaceAll("\\\\", "");
      AnArray = jsonFormattedString.trim();
    }

    Response.ResponseBuilder responseBuilder = Response.ok();
    try {
      String passedObj = AnArray.trim();

      JSONArray array = new JSONArray(passedObj);
      User[] users = new User[array.length()];

      for(int i = 0; i < array.length(); i++) {

        JSONObject jsonObject = (JSONObject) array.get(i);

        Gson gson = new Gson();
        Object object = gson.fromJson(jsonObject.toString(), User.class);

        users[i] = (User) object;

      }

      for(User user : users) {

        try {
            userService.create(user);

        }
        catch(UserException e) {
          responseBuilder = Response.status(Response.Status.PRECONDITION_FAILED).entity("{\"error\":\""
                                                                                        + "Users not created: ("
                                                                                        + e.getMessage() + ")\"}");
        }
      }
    }
    catch(Exception e) {
      e.getMessage();
    }

    return responseBuilder.build();
  }

on the frontend AngularJS

=========================

  $http.post("rest/users",{users:liststringifyed})
                    .success(function (data, status, headers) {
                        $scope.ServerResponse = data;
                        $element.modal('hide');
                          close({type: 'success', msg: 'users created in onego'}, 500);
                    })
                    .error(function (data, status, header, config) {
                        $scope.ServerResponse =  data ;

                        alert(" Errorrs !!!!!! "+i);
                         // createErrorAlert($scope.ServerResponse);

                    });