submit dropdown angularjs spring MVC

1.2k views Asked by At

I have one-to-many relationship between two entities TypeSite and Site. On the front end i have a form (angularJS) used for creation of a new Site with a bunch of fields and drop-down list where user can select type of this site. The form submit successfully without Dropdown ,but when i try submit the form with the combobox i get the following error :

org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'site' on field 'siteesTypeSite': rejected value [Etatique]; codes [typeMismatch.site.siteesTypeSite,typeMismatch.siteesTypeSite,typeMismatch.model.TypeSites,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [site.siteesTypeSite,siteesTypeSite]; arguments []; default message [siteesTypeSite]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'model.TypeSites' for property 'siteesTypeSite'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [model.TypeSites] for property 'siteesTypeSite': no matching editors or conversion strategy found]
    at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:110)

Model :

    public class Sites implements java.io.Serializable {
        private int                 id;
        private TypeSites           siteesTypeSite;
        @JsonBackReference("site-typeSite")
        @ManyToOne
        @JoinColumn(name = "idTypeSite")
        public TypeSites getSiteesTypeSite() {
            return siteesTypeSite;
        }


    public class TypeSites implements java.io.Serializable {
        private int                     idTypeSite;
        private Set<Sites>              sitees= new  HashSet<Sites>(0);

        @JsonManagedReference("site-typeSite")
        @OneToMany(mappedBy = "siteesTypeSite",fetch = FetchType.LAZY)
        public Set<Sites> getSitees() {
            return sitees;
        }

Repository :

public interface SitesRepository extends PagingAndSortingRepository<Sites, Integer> {
        Page<Sites> findBycodeGSMLike(Pageable pageable, String codeGSM);
}

Services class :

@Service
@Transactional
public class SitesService {
    @Autowired
    private SitesRepository siteRepository;
    @Transactional(readOnly = true)
    public void save(Sites site) {
            siteRepository.save(site);
        }
    }

controller class :

@Controller
@RequestMapping(value = "/protected/sites")
public class SitesController {
  private static final String DEFAULT_PAGE_DISPLAYED_TO_USER = "0";   
    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView welcome() {
        return new ModelAndView("sitesList");
    }
   @RequestMapping(method = RequestMethod.POST, produces = "application/json")
    public ResponseEntity<?> create(@ModelAttribute("site") Sites site,
                                    @RequestParam(required = false) String searchFor,
                                    @RequestParam(required = false, 
                                    defaultValue = DEFAULT_PAGE_DISPLAYED_TO_USER) int page,
                                    Locale locale) {
        siteService.save(site);

        if (isSearchActivated(searchFor)) {
            return search(searchFor, page, locale, "message.create.success");
        }

        return createListAllResponse(page, locale, "message.create.success");
    }
}

Angularjs code : $scope.createObject = function (newObjectForm) { if (!newObjectForm.$valid) { $scope.displayValidationError = true; return; } $scope.lastAction = 'create';

        var url = $scope.url;

        var config = {headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}};

        $scope.addSearchParametersIfNeeded(config, false);

        $scope.startDialogAjaxRequest();

        $http.post(url, $.param($scope.sites), config)
            .success(function (data) {
                $scope.finishAjaxCallOnSuccess(data, "#addObjectsModal", false);
            })
            .error(function(data, status, headers, config) {
                $scope.handleErrorInDialogs(status);
            });
    };

On the JSP :

<select ng-model="sites.siteesTypeSite"
        name="siteesTypeSite"               
        ng-options="typesites as typesites.typeSite for typesites in page.source "
        value="{{sites.siteesTypeSite}}" >
        <option value="">-- Select Type site --</option>
        <input type="hidden" name="siteesTypeSite" value="{{sites.siteesTypeSite}}" />
</select><br>

enter image description here

1

There are 1 answers

4
Kwentin On

Your error is explained in the stacktrace : Failed to convert property value of type 'java.lang.String' to required type '.model.TypeSites' for property 'siteesTypeSite';

The value in the dropbox is a string and you are trying to match a TypeSites.

Solution:

I suppose your TypeSites is an Enum. If that's the case just create a function to find the matched value based on the string returned by the dropdown.

<select ng-model="sites.siteesTypeSite"
            name="siteesTypeSiteName"
            ng-options="typesites.typeSite as typesites.typeSite for     typesites in page.source" >
            <option value="">-- Select Type site --</option>
</select>

Create a field siteesTypeSiteName and update your dropbox like I did. Then use the function to get the linked TypeSites.