Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

In a rails project, I add data to database by http.post from angularjs controller. I have below code to do this:

RestaurantIndexCtrl.js.coffee:

restauranteur.controller 'RestaurantIndexCtrl', ['$scope', '$location', '$http', ($scope, $location, $http) ->
$scope.restaurants = []
  $http.get('./restaurants.json').success((data) ->
    $scope.restaurants = data
  )
  $scope.addRestaurant = (test) ->
    $http({
      url: '/restaurants#create',
      method: "POST",
      data: JSON.stringify({name:test}),
      headers: {'Content-Type': 'application/json'}
    })

]

templates/restaurants/index.html:

<form ng-submit="addRestaurant(restaurant.name)">
    <input type="text" ng-model="restaurant.name">
    <button>Register</button>
</form>
<ul ng-repeat="restaurant in restaurants">
    <li><a ng-click="viewRestaurant(restaurant.id)">{{ restaurant.name }}</a></li>
</ul>

And below code in rails project: restaurants_controller.rb:

def create
    @restaurant = Restaurant.new(restaurant_params)

    respond_to do |format|
      if @restaurant.save
        format.html { redirect_to @restaurant, notice: 'Restaurant was successfully created.' }
        format.json { render action: 'show', status: :created, location: @restaurant }
      else
        format.html { render action: 'new' }
        format.json { render json: @restaurant.errors, status: :unprocessable_entity }
      end
    end
  end

Now, when I comlete the textfield and post data to rails project, data aren't add to database until I refresh the page. When I refresh, data is add to database and show data on index.html.

  1. I want when I copmlete the textfield and post to rails controller by angularjs, new data are add to database and show on index.html without reloding. How can I do this? The problem is exist in rails controller or angularjs code?

  2. I set unique validation for restaurant name, now if I send a name that exist in database, rails controller doesn't permit to add data to database. How can I get error that rails generate and show to user in angularjs html code?

Note: I use external view for angularjs and put templates in public folder and then route the url by ngRoute.

main.js.coffee:

@restauranteur = angular.module('restauranteur', ['ngRoute'])

@restauranteur.config(['$routeProvider', ($routeProvider) ->
  $routeProvider
  .when('/restaurants', {
    templateUrl: '../templates/restaurants/index.html',
    controller: 'RestaurantIndexCtrl'
  })
    .otherwise({
        templateUrl: '../templates/home.html',
        controller: 'HomeCtrl'
      })
])
share|improve this question

1 Answer 1

One approach would be to make your create method return the updated @restaurants and then update the scope in a callback on the angular side. Real rough implementation:

def create
    @restaurant = Restaurant.new(restaurant_params)

    if @restaurant.save
      render json: Restaurant.all, status: 200
    else
      #whatever
    end
  end
end

and on the frontend:

$scope.addRestaurant = function(test) {
  var data = {name: test}
  $http.post('/restaurants', data).success(function(data){
    $scope.restaurants = data;
  })
}

Another approach to avoid the round-trip to the server is to assume success and push the new object into the existing $scope.restaurants on the client side. This poses some issues because of your validations.

For the validations, the errors are rendered here in your controller already:

format.json { render json: @restaurant.errors, status: :unprocessable_entity }

You'll have to add an .error handler to your $http call and set the returned data in $scope.errors or something to show to the user.

You will probably also want to abstract your api calls into an angular service so you can reuse the code in other parts of the application. Also consider reading up on the resolve attribute of $routeProvider and using that to resolve your data before the view is loaded.

share|improve this answer
    
I use your guide, but when I post data to database and data is saved, I get this error: Completed 406 Not Acceptable in 114ms.ActionController::UnknownFormat(ActionController::UnknownFormat): app/controller/restaurants_controller.rb:32:in create. –  mgh Aug 5 at 10:22
    
Right, you probably need to play with the data format. Look at your server logs for more information on the error. It's probably going to be something like var data = {restaurant: {name: test}} –  user2936314 Aug 5 at 10:25
    
Data is true, because new restaurants add correctly to database. But I don't know about Completed 406 Not Acceptable. and the data don't send to angularjs after save to database until I reload the page again. –  mgh Aug 5 at 10:42
    
was a syntax error, see my edit for the create action in your controller. –  user2936314 Aug 5 at 10:51
    
Thats right, but when I add data to database, I can just show latest record in view and render json: Restaurant.all, status: 200 is not working and if working, data is not send from rails controller to angularjs controller. Do you know the reasons? –  mgh Aug 5 at 11:31

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.