blaiso
blaiso

Reputation: 491

AngularJs how to access Model Attribute value from Spring MVC controller

I have a Spring MVC Controller returning a page with an attribute as followed

@RequestMapping(method = RequestMethod.GET, value = "/create")
public ModelAndView getAddAccountView() {
    ModelAndView model = new ModelAndView("protected/accounts/AccountAddView");
    List<Client> clients=clientService.findAll();
    model.addObject("listClients", clients);
    return model;
}

Client is a @Entity

in my AccountAddView.jsp file, i'm trying to use the ng-init as follow:

<div class="row-fluid" ng-controller="accountsController as ctrl" ng-init="clients=${listClients}">

and in my app.js, in my controller, i try to access the list of client as followed

var listOfClients=$scope.clients;

but I'm still getting the following error

angular.min-1.5.3.js:116 Error: [$parse:lexerr] http://errors.angularjs.org/1.5.3/$parse/lexerr?p0=Unexpected%20nextharacter%20&p1=s%2033-33%20%5B%40%5D&p2=clients%3D%5Bsoftbank.ui.model.Client%4042%2C%softbank.ui.model.Client%4041%2C%softbank.ui.model.Client%4043%5D
at Error (native)
at http://localhost:8080/softbank/resources/js/angular.min-1.5.3.js:6:416
at gc.throwError (http://localhost:8080/softbank/resources/js/angular.min-1.5.3.js:212:149)
at gc.lex (http://localhost:8080/softbank/resources/js/angular.min-1.5.3.js:211:16)
at Object.ast (http://localhost:8080/softbank/resources/js/angular.min-1.5.3.js:216:103)
at Object.compile (http://localhost:8080/softbank/resources/js/angular.min-1.5.3.js:225:232)
at hc.parse (http://localhost:8080/softbank/resources/js/angular.min-1.5.3.js:252:380)
at e (http://localhost:8080/softbank/resources/js/angular.min-1.5.3.js:123:317)
at m.$eval (http://localhost:8080/softbank/resources/js/angular.min-1.5.3.js:142:463)
at pre (http://localhost:8080/softbank/resources/js/angular.min-1.5.3.js:271:500)

please what is wrong here. why is ng-init generating this errors? thanks in advance for your answer.

Upvotes: 3

Views: 11004

Answers (2)

Ankit Pandoh
Ankit Pandoh

Reputation: 577

Old Post but still I would like to answer so that anyone who is using Angular with Spring MVC get some help.
Using model attribute is a challenge with Angular. Earlier I was setting employee data in model attribute like mav.addObject("employee",employee), but when I was trying to use ${employee} inside the jsp, Angular wasn't able to set the java object using ng-init directive because it was expecting a java script object. So I set json inside the model Attribute mav.addObject("employeeJson", empJson) and parsed it using json.Parse() to convert it into Java Script Object and was able to use it with Angular expressions on the jsp
Below are the steps which I followed:
1. Spring Controller
In your controller, set json in the model attribute. For e.g.
mav.addObject("employeeJson", empJson);
Make sure before adding it to ModelAttribute, replace quotes with html entity " otherwise there will be error while parsing the json empJson.replaceAll("\"", "\&\quot;");
2. Jsp
Use angular init directive, data-ng-init="yourController.getEmployeeData('${employeeJson}')"
3. In Angular js
parse this json to get the json
var vm = this;
vm.employee = {};
vm.getEmployeeData = function(employeeJson){, vm.employee = JSON.parse(employeeJson); };
4. Inside jsp
I can access employee name as {{yourController.employee.firstName}}

Upvotes: 3

ChiefTwoPencils
ChiefTwoPencils

Reputation: 13940

I'm just starting with Angular with Spring so what I'll do is explain how I did it and you can see if it's a viable option for you.

For one, I didn't try to go through the ModelAndView for my data. I let my "regular" controller return the view but got my data via the angular controller and service along with a @RestController on the Spring side (that's two separate Spring controllers then).

To return only the view you have at least two options that I'm aware of. One, you can just return a ModelAndView without a model like so:

public ModelAndView yourView() {
    return new ModelAndView("yourView");
}

Or two, return the name of the view as a string like so:

public String yourView() {
    return "yourView";
}

In both cases you'd obviously need the correct @RequestMapping.

In my view I had an angular controller function that made a call to my associated angular service which in turn called my @RestController and so on. I initiated the data like so:

ng-controller="MyController as ctrl" ng-init="ctrl.allThings()"

Examples of the code:

Angular controller:

self.allThings = function () {
        ThingService.things()
            .then(
                function (data) {
                    self.things = data;
                },
                function (errResponse) {
                    console.error("Error retrieving thing list");
                }
            );
    };

Angular service:

    things: function() {
        return $http.get('/things')
            .then(
                function(response) {
                    return response.data;
                },
                function (errResponse) {
                    return $q.reject(errResponse);
                }
            );
    },

Spring REST controller:

@RequestMapping(value = "/things", method = RequestMethod.GET)
public List<Thing> things() {
    return thingService.findAll();
}

I imagine you know the remaining code for the Spring side. Jackson will handle all the object conversions for you.

Upvotes: 3

Related Questions