Ajax on Ror, Networkerror - ruby-on-rails

I'm working in a simple increment fonction who is not working. In my console I have this error "NetworkError: 404 Not Found - ..../test/increment_nbr" and I'm not able to fix it.
Html:
<button id="incr">AJAX2</button>
<script>
$("#incr").on("click", function(e) {
e.preventDefault();
$.ajax({
url: "/test/increment_nbr",
dataType: "json",
type: "POST",
success: function(data) {
}
});
})
</script>
My controller:
respond_to :html, :json
def increment_nbr
#user = User.find(params[:id])
#user.increment! :nbr_set
render json: { nbr: #user.nbr_set }.to_json
end
Routes:
resources :test do
member do
put :increment_nbr
post :increment_nbr
end
end

Your routing is incorrect - you've defined your two increment_nbr routes as member routes, meaning they operate on an instance of your parent test route and would generate URLs like /test/2/increment_nbr.
See http://guides.rubyonrails.org/routing.html#adding-more-restful-actions for more information

Related

Rails Ajax not displaying the result

I have created a new controller, that in future will be responsible only for translating strings for different objects.
Here is the code of the controller:
# frozen_string_literal: true
class Api::TranslationsController < AuthenticatedController
def translate_string
#translated_string = GoogleTranslator.translate('hello', 'de')
render json: {translated_string: #translated_string.to_json}
end
helper_method :translate_string
private
def translations_params
params.permit(
:id,
:translated_string
)
end
end
It is placed in directory controllers/api/translations_controller. Here is the part of routes:
namespace :api do
resource :translations do
member do
get 'translate_string'
end
end
end
And here is part of my html.erb to call JS function:
<%= image_tag "google-icon.png", id: "google_icon", onclick: "test_transl()",
remote: true%>
And here is my JS code, currently only with Ajax:
<script>
function test_transl(){
$.ajax({
type: "GET",
url: "/api/translations/translate_string",
dataType: "json",
success:function (result){
console.log(result)
}
})
}
</script>
I expect this ajax code to translate the world 'hello' on German and get value #translated_string - 'hallo' in console but nothing happens except the fact, that the error I got is 'statusText: "parsererror"'. What may be wrong?
I finally found what was wrong with my code. The problem was with fact that I didn't pass sessions token in ajax. So now my ajax code will look like this:
$.ajax({
type: "GET",
headers: {
"Authorization": "Bearer " + window.sessionToken
},
url: "/api/translations/translate_string",
dataType: "json",
success: function(result){
console.log(result);
},
error: function (result){
console.log(result, this.error)
}
})
And def from controller like this:
def translate_string
#translated_string = GoogleTranslator.translate('hello', 'de')
render json: #translated_string.to_json
end
The output in console is: "hallo".

Passing in rails routes to AJAX url value

I have an app where a user has a portfolio that has many positions and each position has many movements. So the url for an associated movement index page for a particular position looks like: portfolio_position_movements. I have an index page with and the controller action looks like
def index
#movements = #position.movements.all
respond_to do |format|
format.html
format.json { render json: #movements}
end
end
My ajax call in my movements.js file is this:
var loadData = function(){
$.ajax({
type: 'GET',
contentType: 'application/json; charset=utf-8',
url: ?,
dataType: 'json',
success: function(data){
drawBarPlot(data);
},
failure: function(result){
error();
}
});
};
How can I pass in a dynamic route path so this will work with the movement index on any position object?
You can use erb tags in js files, for me i did it as the following:
#edit.js.erb
$modal = $('.modal'),
$modalBody = $('.modal .modal-body'),
$modalHeading = $('.modal .modal-heading');
$modalHeading.html("Edit <%= #student.full_name.titleize %>'s information");
$modalBody.html("<%= escape_javascript(render 'edit_student') %>");
$modal.modal();
Note: the file extension is .js.erb so rails can process it. I was calling a modal form and the edit method in students_controller.rb was:
def edit
#student = Student.find(params[:id])
respond_to do |format|
format.html # edit.html.erb
format.js # edit.js.erb
format.json { render json: #student }
end
end
Edit:
You can embed the JS code inside html.erb and use rails routes like:
<script>
var loadData = function(){
$.ajax({
type: 'GET',
contentType: 'application/json; charset=utf-8',
url: <%= my_ajax_path %>,
dataType: 'json',
success: function(data){
drawBarPlot(data);
},
failure: function(result){
error();
}
});
};
</script>
What is my_ajax_path?
Is a rails route defined in routes.rb for example i need a list of all available sections that students can apply to using ajax so i did the following:
1- defined a method in students_controllers.rb like this one:
def available_sections
batch_id = (params[:batch_id].nil? || params[:batch_id].empty?) ? 0 : params[:batch_id].to_i
if batch_id == 0
#sections = [].insert(0, "Select Section")
else
batch = Batch.find(params[:batch_id])
# map to name and id for use in our options_for_select
#sections = batch.sections.map{|a| [a.section_name, a.id]}
end
end
2- added a route to it in routes.rb
resources :students do
collection do
get :available_sections
post :create_multiple
end
end
3- Inside new.html.erb:
<script type="text/javascript">
$(document).ready(function() {
$('.student_section_id').hide();
$('#student_batch').change(function() {
$.ajax({
url: "/students/available_sections",
data: {
batch_id : $('#student_batch').val()
},
dataType: "script",
success: function () {
if (+$('#student_batch').val() > 0)
{
$('.student_section_id').fadeIn();
}
else
{
$('.student_section_id').fadeOut();
}
}
});
});
});
</script>
Forget about that messy code :D as it was my first steps but you get the point, and for this line url: "/students/available_sections" it should be using rails routes you can get it by calling rails routes from the command line to get a list of all your application routes

Ruby on rails Ajax call showing 404 error

I am making and ajax call to hit the controller but it is showing the 404 error:
My controller method is like:
def get_user_time
if(params[:user])
#user_time_checks = UserTimeCheck.where(:user_id => params[:user])
end
end
And my route for this is like:
post "user_time_checks/get_user_time"
And my ajax script is like:
function get_user_time(id) {
var user_id = id;
if(user_id != ''){
$.ajax({
url:"get_user_time?user="+user_id,
type:"POST",
success: function(time){
console.log(time);
},error: function(xhr,response){
console.log("Error code is "+xhr.status+" and the error is "+response);
}
});
}
}
Try this:
$.ajax({
url:"user_time_checks/get_user_time",
type:"POST",
data: {
user: user_id
},
success: function(time){
console.log(time);
},error: function(xhr,response){
console.log("Error code is "+xhr.status+" and the error is "+response);
}
});
Also make sure you really need to do POST method and that rails route does not require specific paramater like :user_id. Basically check the output from
rake routes | grep get_user_time
Your route should be:
post "user_time_checks/get_user_time" => "user_time_checks#get_user_time"
Also, since the purpose of the request is to get some data, you should make it a GET request instead. So:
function get_user_time(id) {
var user_id = id;
if(user_id != ''){
$.get("get_user_time",
{user: user_id})
.success(function(time) {
console.log(time);
})
.error(function(xhr,response){
console.log("Error code is "+xhr.status+" and the error is "+response);
});
}
}
Lastly, maybe you should tell the controller to be able to repond_to json:
def get_user_time
if(params[:user])
#user_time_checks = UserTimeCheck.where(:user_id => params[:user])
respond_to do |format|
format.html # The .html response
format.json { render :json => #user_time_checks }
end
end
end

Consuming a rails json api with angularjs

I'm new to angularjs/clientjs and would like to consume a rails json api with angularjs. After some research I wrote the ff: code but when I visit http://localhost:3000/users I get plain json. Angularjs is not being called to render a view.
How can I render an angularjs view that formats and shows the data a rails json api returns?
rails/routes
app::Application.routes.draw do
get 'main/index' => 'main#index'
resources :users, defaults: {format: :json}
end
rails/users_controller.rb
def index
#users = User.all
end
rails/main_controller.rb
def index
# blank
end
rails/application layout
..
<html ng-app='gold'>
..
<div ng-view>
<%= yield %>
</div>
..
app/assets/templates/main/index.html
app/assets/templates/users/index.html
app/assets/javascripts/main.js
var myApp = angular.module('gold', ['ngRoute', 'ngResource']);
myApp.config(function($routeProvider, $locationProvider, $httpProvider) {
console.log("in router")
$httpProvider.defaults.headers.common['X-CSRF-Token'] =
$('meta[name=csrf-token]').attr('content');
$locationProvider.html5Mode(true);
$routeProvider.
when('/users', {
templateUrl: '../assets/users/index.html',
controller: 'UsersController'
}).when('/main/index', {
templateUrl: '../assets/main/index.html',
controller: 'MainController'
}).otherwise({
redirectTo: '/'
});
});
app/assets/javascripts/services/UserService.js
myApp.factory('UserService', ['$resource', function($resource) {
console.log("in user service")
return $resource('/users/:id', {id: '#id'}, {
index: { method: 'GET', isArray: true },
create: { method: 'POST' },
show: { method: 'GET' },
update: { method: 'PUT', params: {id: '#id'} }
//delete: { method: 'DELETE', params: {id: '#id'} }
});
}]);
app/assets/javascripts/controllers/UsersController.js
myApp.controller('UsersController', ['$scope', 'UserService', function($scope, UserService) {
console.log("in user controller")
$scope.users = UserService.query();
}]);
I think I know what you are trying, as I'm working on similar problem.
Once Rails sends json, that is it. You can't ask it to render other
html/erb and use it to interpret the json data. see this answer on
How can we use rails routes with angularjs in a DRY way?
To achieve both Rails + Angular routing at the same time (render Rails pages with URL, json data with ajax/api calls), I have setup a #view model contains Angular page url for the request + json data.
For a normal HTML request: default.html.erb translates the #view variable to .js using a "jsonService.js.erb", and render the angular page in #view.
For ajax/api calls: Setup routes using angular.config as you did for render page, and add resolve: fetchData(controller#action) to fetch the json data from Rails controllers and use it in the angular page.
Rails Controller:
respond_to do |format|
format.json { #view }
format.html { render 'layouts/default' }
end
default.html.erb
<script id="jsonService"><%= render "layouts/json_service.js" %></script>
<div ng-include ="content.view.template"></div>
Angular
You can use what you got for angular.config. Just remember to use ng-href or ng-click for the links in json/api calls.
if you have dynamic routing in the angular.config, remember to call $scope.$digest after you replaced the html content.

Ajax call is returning error from action controller in rails

on change of a dropdown value i am trying to populate other dropdown list value.
Here i have added my new action in routes.rb :
resources :appointments do
collection do
get :getdata
end
end
This is my js code :
$("#appointment_department_id").change(function(){
//on change of department dropdown.
$.ajax({
url: "/appointment/getdata",
type: "GET",
data: {department_id: $(this).val()},
success: function(data){
alert(data);
}
error: function(data){
alert(data);
}
});
});
here is my action in controller file :
def getdata
#dept_id = params[:department_id]
department_name = #dept_id
#all_doctors = User.all; #will write my custom query later.
end
But on call to this action, it's returning error:
"NetworkError: 404 Not Found - http://localhost:3000/appointment/getdata?department_id=5"
(checked in firebug)
the error is in the ajax url, in the ajax request you are using 'appointment/getdata', but in routes you have defined appointments,
so use
$("#appointment_department_id").change(function(){
//on change of department dropdown.
$.ajax({
**url: "/appointments/getdata",**
type: "GET",
data: {department_id: $(this).val()},
success: function(data){
alert(data);
}
error: function(data){
alert(data);
}
});
});
Where's your respond_to in your controller?
If you're sending an Ajax request, you'll have to either define respond_to "JS" or "JSON" like this:
def getdata
respond_to do |format|
format.js
end
end
You could also do it like this:
Class Controller
respond_to :html,:js, :json
def getdata
respond_with(#custom_vars)
end
end
i think you forget "s" of "appointment" word in url: "/appointment/getdata", so try to add "s" like this :
$.ajax({
url: "/appointments/getdata",
...
...

Resources