"NetworkError: 404 Not Found" - $.post() with jQuery - javascript

Here is js code in our Rails 3.2 app responding to change of fields whose ids start with 'order_order_items_attributes':
$(function (){
$(document).on('change', "[id^='order_order_items_attributes'][id$='_name']", function (){
$.post(window.location, $('form').serialize(), null, "script");
return false;
});
});
The $.post() causes the error:
"NetworkError: 404 Not Found - http://localhost:3000/po/orders/new?parent_record_id=4&parent_resource=ext_construction_projectx%2Fprojects&project_id=4%22"
Here is the window.location:
If we replace $.post() with $.get(), then the code works fine and fires up the ajax response on the server:
$.get(window.location, $('form').serialize(), null, "script"); #works!
But we have to use $.post() because of the large amount of data being posted to the server. The jquery document shows that $.get() and $.post() have exactly the same format. What we missed here with $.post()?
Update
rake routes output:
Routes for PurchaseOrderx::Engine:
search_order_items GET /order_items/search(.:format) purchase_orderx/order_items#search
search_results_order_items GET /order_items/search_results(.:format) purchase_orderx/order_items#search_results
stats_order_items GET /order_items/stats(.:format) purchase_orderx/order_items#stats
stats_results_order_items GET /order_items/stats_results(.:format) purchase_orderx/order_items#stats_results
order_items GET /order_items(.:format) purchase_orderx/order_items#index
POST /order_items(.:format) purchase_orderx/order_items#create
new_order_item GET /order_items/new(.:format) purchase_orderx/order_items#new
edit_order_item GET /order_items/:id/edit(.:format) purchase_orderx/order_items#edit
order_item GET /order_items/:id(.:format) purchase_orderx/order_items#show
PUT /order_items/:id(.:format) purchase_orderx/order_items#update
DELETE /order_items/:id(.:format) purchase_orderx/order_items#destroy
search_orders GET /orders/search(.:format) purchase_orderx/orders#search
search_results_orders GET /orders/search_results(.:format) purchase_orderx/orders#search_results
stats_orders GET /orders/stats(.:format) purchase_orderx/orders#stats
stats_results_orders GET /orders/stats_results(.:format) purchase_orderx/orders#stats_results
event_action_order GET /orders/:id/event_action(.:format) purchase_orderx/orders#event_action
acct_approve_order PUT /orders/:id/acct_approve(.:format) purchase_orderx/orders#acct_approve
acct_reject_order PUT /orders/:id/acct_reject(.:format) purchase_orderx/orders#acct_reject
gm_approve_order PUT /orders/:id/gm_approve(.:format) purchase_orderx/orders#gm_approve
gm_reject_order PUT /orders/:id/gm_reject(.:format) purchase_orderx/orders#gm_reject
gm_rewind_order PUT /orders/:id/gm_rewind(.:format) purchase_orderx/orders#gm_rewind
submit_order PUT /orders/:id/submit(.:format) purchase_orderx/orders#submit
list_open_process_orders GET /orders/list_open_process(.:format) purchase_orderx/orders#list_open_process
orders GET /orders(.:format) purchase_orderx/orders#index
POST /orders(.:format) purchase_orderx/orders#create
new_order GET /orders/new(.:format) purchase_orderx/orders#new
edit_order GET /orders/:id/edit(.:format) purchase_orderx/orders#edit
order GET /orders/:id(.:format) purchase_orderx/orders#show
PUT /orders/:id(.:format) purchase_orderx/orders#update
DELETE /orders/:id(.:format) purchase_orderx/orders#destroy
root / purchase_orderx/orders#index
Here is the rake routes output for purchase order engine. Most of the routes are not relevant to the question and still listed as it is.
here is routes.rb:
resources :order_items do
collection do
get :search
get :search_results
get :stats
get :stats_results
end
end
resources :orders do
collection do
get :search
get :search_results
get :stats
get :stats_results
end
end
Workflow related actions were removed in routes.rb for easy read.

Your backend routing is not properly routing that URL to a valid controller when using the POST HTTP verb. In the root of your Rails project in the terminal, run rake routes to see all available routes, and where they end up. Without seeing your routes.rb I can't explain exactly what's wrong, but it's definitely a backend routing issue.
I wouldn't recommend what some of the comments are saying, to just "stick this in routes.rb and it will work". Your routes should be well maintained and using the correct Route helper for the job. If you throw misc. routes in there to solve problems as they come up, you'll end up with a pile of spaghetti for your routing, and maintenance of your application will become more difficult over time.
Edit: Updated to reference the update from the question
The current page URL is /po/orders/new. Looking at your rake routes output, this maps to new_order_path, evidenced by this row:
new_order GET /orders/new(.:format) purchase_orderx/orders#new
If you look directly above it, you'll see the real route for the create action:
POST /orders(.:format) purchase_orderx/orders#create
This create action is a POST to orders_path, which resolves as /po/orders/. If you POST to this URL, everything should work. If you want to be able to post to URL you're currently using and have it work, just modify your routes.rb to match this:
resources :order_items do
collection do
get :search
get :search_results
get :stats
get :stats_results
end
end
resources :orders do
# Manually route POSTs to /new to the create action
post "/new", :controller => :orders, :action => :create
collection do
get :search
get :search_results
get :stats
get :stats_results
end
end
Now, when you make a POST to this URL (/po/orders/new, it will hit the OrdersController create method. You can still hit this method by POSTing to /po/orders as well (as I recommended above).

Related

Express req.param deprecated syntax

On Node.js I am getting this error, in some JavaScript code:
express deprecated req.param(name): Use req.params, req.body,
Here is the relevant code:
response.render('pages/' + displayPage, {
MYVAR: request.param('MYVAR'),
MYVAR2: request.MYVAR,
MYVAR3: request.params.MYVAR
});
In other words this line is deprecated
MYVAR: request.param('MYVAR'),
But, it does the job (at least for now).
And the other type of syntax I tried, by guessing or by finding on the net after searching, all failed.
Including these lines:
MYVAR2: request.MYVAR,
MYVAR3: request.params.MYVAR
and a few more options that would be pointless to list here.
So the question is: what is the right syntax to use?
Here is some more information, added by editing the post after reading some comments:
I send the request parameters this way:
https://myapp.herokuapp.com/branch?MYVAR=64.39
Inside index.js the code processing the /branch is:
response.render('pages/' + displayPage, {
MYVAR: request.param('MYVAR'),
MYVAR2: request.params.MYVAR,
MYVAR3: request.params['MYVAR']
});
Inside the branch.ejs file I have placed the following in order to see what I am getting:
<body bgcolor=#221122E>
<b>MYVAR=<%= MYVAR %></b><br/>
<b>MYVAR2=<%= MYVAR2 %></b><br/>
<b>MYVAR3=<%= MYVAR3 %></b><br/>
......
And finally this is what I can see in the browser, displayed by branch.ejs:
MYVAR=64.39
MYVAR2=
MYVAR3=
It shows that the variable passed with the old syntax arrives as expected, but not the other ones.
Which of the variants is needed depends on how you send request parameters:
You need to use req.query.MYVAR if your request uses the GET method with parameters after the ? like /path?MYVAR=123.
If you have your parameters in the path (e.g. /path/:MYVAR in your express get call), req.params.MYVAR is correct.
If you use POST or PUT, you need to use req.body.MYVAR, because of the data is transferred in the body. Since express doesn't parse the body , you need to include and use an additional package like body-parser
Instead of using:
request.param('MYVAR')
You are supposed to use:
request.params['MYVAR']
// Or this:
request.params.MYVAR

Getting BadMethodCallException when using JavaScript package

I am sending a get request to a route and my controller picks up a collection from the database and then puts it into a javascript variable using Laracasts Javascript class (can be found here. It is a Php variable to javascript variable transformer- and I think it does so in a pretty standard way)
I do so like this:
$unReadNotifications = \App\Notification::join('users', 'notifications.notifier_user_id', '=', 'users.id')
->where('notifications.user_id', '=', $user->id)
->where('is_read', '=', 0)
->select('users.id as notifierId', 'users.username as username', 'notifications.id as id', 'notifications.subject as subject', 'notifications.body as body', 'notifications.notifiable_type as notifiable_type', 'notifications.notifiable_id as notifiable_id')
->orderBy('notifications.created_at', 'desc')
->with('notifiable')->get();
JavaScript::put(['unReadNotifications' => $unReadNotifications]);
and I am getting:
BadMethodCallException in Builder.php line 2405:
Call to undefined method Illuminate\Database\Query\Builder::getTagNameListAttribute()
I did a grep -r getTagNameListAttribute * and the only place it appears in my project is in a model (the model is actually related: some of my notifications belongTo a Notifiable which belongsTo a Content- this Content model is the one that has this method called getTagNameListAttribute and there is an appends array in that model which appends the output of that method to the model like so: protected $appends = ['tag_name_list'];).
The error is happening when running JavaScript::put(['unReadNotifications' => $unReadNotifications]); because when I put a dd right before this, all is fine, and anytime after I still get the error.
I am guessing that the Javascript::put is somehow calling some sort of get on a notification's notifiable's Content. This code works when all of the notifications are the kind that their notifiable have a Content, but now when the notification's notifiable does not have a content, I am getting this error. But I don't really understand why it would do that.
Any ideas as to what is going on?

Reddit Api Error trying to get reddit self text via snoocore node.js

I'm tryng to get the self.text on a post and using this route:
reddit('/r/Denmark/comments/2jc5yk/how_to_live_in_denmark.json').listing({
context: 1,
limit: 10,
sort: 'hot',
})
.then(function(result) {
console.log(result);
});
I have also tried using .get(), without .json and without /how_to_live_in_denmark but still the same error.
When I input the route in my browser, I get the desired JSON.
The error i get:
Uncaught Error: Invalid path provided! This endpoint does not exist. Make sure that your call matches the routes that are defined in Reddit's API documentation
What am i doing wrong?
Update: 2015-02-09
Snoocore now accepts URLS's with embedded values and does not require placeholders if you do not wish to use them.
I'm the creator of this API wrapper. I'll have to monitor StackOverflow a little bit more to catch these quicker. Feel free to open new issues on GitHub as well when you get stuck on something for a quicker response!
It looks like you are trying to call this endpoint:
GET /r/[subreddit]/comments/article
Basically anything that is in brackets is optional in Snoocore, and anything in italics is an URL parameter that you will need to define placeholders for in the call (using $parameter). More information on this can be read in the documentation (feel free to ask questions or improve upon the documentation if it isn't clear!)
So in your case, you will want to do this:
reddit('/r/$subreddit/comments/$article').get({
$subreddit: 'Denmark',
$article: '2jc5yk',
context: 1,
limit: 10,
sort: 'hot'
}).done(function(result) {
console.log(result);
});
Note that instead of defining the url parameters in the call, the are now referenced by $subreddit and $article respectivly.
Note that comments are not a listing, and therefore can't use the listings interface as you tried to do in your question.

Making code using JavaScript for dependent selects RESTful

Ruby 2.0.0, Rails 4.0.3, Windows 8.1 Update, PostgreSQL 9.3.3
I have code that uses JavaScript to power dependent selects. To do so, it references a controller method that retrieves the data for the following select. I'm told that, because that method is non-standard, this is not RESTful.
I understand that REST is a set of specific constraints regarding client/server communications. I've read some information about it but certainly don't have in-depth knowledge. I am curious about the impact and resolution. So, regarding the question about my configuration and REST: First, would that be accurate that it is not RESTful? Second, how does that impact my application? Third, what should/could I do to resolve that? Providing one example:
The route is: (probably the concern?)
post 'cars/make_list', to: 'cars#make_list'
This is the first select: (OBTW, I use ERB but removed less than/percent)
= f.input(:ymm_year_id, {input_html: {form: 'edit_car', car: #car, value: #car.year}, collection: YmmYear.all.order("year desc").collect { |c| [c.year, c.id] }, prompt: "Year?"})
This is the dependent select:
= render partial: "makes", locals: {form: 'edit_car', car: #car}
This is the partial:
= simple_form_for car,
defaults: {label: false},
remote: true do |f|
makes ||= ""
make = ""
make = car.make_id if car.class == Car and Car.exists?(car.id)
if !makes.blank?
= f.input :ymm_make_id, {input_html: {form: form, car: car, value: make}, collection: makes.collect { |s| [s.make, s.id] }, prompt: "Make?"}
else
= f.input :ymm_make_id, {input_html: {form: form, car: car, value: make}, collection: [], prompt: "Make?"}
end
end
JS:
$(document).ready(function () {
...
// when the #year field changes
$("#car_ymm_year_id").change(function () {
var year = $('select#car_ymm_year_id :selected').val();
var form = $('select#car_ymm_year_id').attr("form");
var car = $('select#car_ymm_year_id').attr("car");
$.post('/cars/make_list/',
{
form: form,
year: year,
car: car
},
function (data) {
$("#car_ymm_make_id").html(data);
});
return false;
});
...
});
And the method:
def make_list
makes = params[:year].blank? ? "" : YmmMake.where(ymm_year_id: params[:year]).order(:make)
render partial: "makes", locals: {car: params[:car], form: params[:form], makes: makes}
end
If I had to describe if, being RESTful means that:
You provide meaningful resources names
You use the HTTP verbs to express your intents
You make proper use of HTTP codes to indicate status
Provide meaningful resource names
As you probably heard it before, everything in REST is about resources. But from the outside, it's just the paths you expose. Your resources are then just a bunch of paths such as:
GET /burgers # a collection of burgers
GET /burger/123 # a burger identified with id 123
GET /burger/123/nutrition_facts # the nutrition facts of burger 123
POST /burgers # with data: {name: "humble jack", ingredients: [...]} to create a new burger
PUT /burger/123 # with data: {name: "chicken king"} to change the name of burger 123
For instance, if you had a path with the url
GET /burger_list?id=123
That would not be considered good practice.
It means you need to think hard about the names you give your resources to make sure the intent is explicit.
Use HTTP verbs to express your intents
It basically means using:
GET to read a resource identified by an identifier (id) or a collection of resources
PUT to update a specific resource that you identify by an identifier (id)
DELETE to destroy a specific resource that you identify by an id
POST to create a new resource
Usually, in Rails, those verbs are, by convention, used to map specific actions in your controller.
GET goes to show or index
PUT goes to update
DELETE goes to destroy
POST goes to create
That's why people usually say that if you have actions in your controllers that don't follow that pattern, you're not "RESTful". But in the end, only the routes you expose count. Not really your controller actions. It is a convention of course, and conventions are useful for readability and maintainability.
You make proper use of HTTP codes to indicate status
You already know the usual suspects:
200 means OK, everything went fine.
404 means NOT FOUND, could not find resource
401 means UNAUTHORIZED, authentication failed, auth token invalid
500 means INTERNAL SERVER ERROR, in other words: kaput
But there are more that you could be using in your responses:
201 means CREATED, it means the resource was successfully created
403 means FORBIDDEN, you don't have the privileges to access that resource
...
You get the picture, it's really about replying with the right HTTP code that represents clearly what happens.
Answering your questions
would that be accurate that it is not RESTful?
From what I see, the first issue is your path.
post 'cars/make_list', to: 'cars#make_list'
What I understand is that you are retrieving a collection of car makes. Using a POST to retrieve a collection is against REST rules, you should be using a GET instead. That should answer your first question.
how does that impact my application?
Well, the impact of not being restful in your case is not very big. It's mainly about readability, clarity and maintainability. Separating concerns and putting them in the right place etc... It's not impacting performance, nor is it a dangerous issue. You're just not RESTful and that makes it more complicated to understand your app, in your case of course.
what should/could I do to resolve that?
Besides the route problem, the other issue is that your action is called make_list and that doesn't follow Rails REST conventions. Rails has a keyword to create RESTful routes:
resources :car_makes, only: [:index] # GET /car_makes , get the list of car makes
This route expresses your intent much better than the previous one and is now a GET request. You can then use query parameters to filter the results. But it means we need to create a new controller to deal with it.
class CarMakesController < ApplicationController
def index
makes = params[:year].blank? ? "" : YmmMake.where(ymm_year_id: params[:year]).order(:make)
render partial: "makes", locals: {car: params[:car], form: params[:form], makes: makes}
end
private
# Strong parameters stuff...
end
And of course we also need to change your jquery to make a GET request instead of a POST.
$(document).ready(function () {
...
// when the #year field changes
$("#car_ymm_year_id").change(function () {
// ...
$.get({
url: '/car_makes',
data: {
form: form,
year: year,
car: car
},
success: function (data) {
$("#car_ymm_make_id").html(data);
});
return false;
});
...
});
This is a much better solution, and it doesn't require too much work.
There is an excellent tutorial on REST on REST API tutorial, if you want to know more about the specifics. I don't know much about the small details, mostly what is useful on a day to day basis.
Hope this helps.

Ruby on Rails 3.1 : error with "render" in javascrtip (AJAX) from RailsCasts (Search, Sort, Paginate with AJAX)

My code is from: RailsCasts: Search, Sort, Paginate with AJAX
I have this error:
undefined method render for #<#<Class:0x9e54e54>:0xa860f24>
(in /var/www/final/.../app/assets/javascripts/application.js.erb)
My application.js.erb:
$(function() {
$("#zoznam_render th a, #zoznam_renders .pagination a").live("click", function() {
$("#zoznam_render").html("**<%=j render 'zoznam' %>**");
return false;
}); });
In index.html.erb render 'zoznam'(_zoznam.html.erb) is OK. "zoznam/index" is list of my products with custom sql select. It´s all OK but "bold" script is not good. '
from TheCompWiz:
original forum
Ok... I think I found a fix for rails 3.1. The trick is to keep from using assets. You need the page to be rendered. This may seem hack-ish... I agree... but it does work. This can probably be better refined in the future.
What you need to do, is add an entry in the routes file before the "resources" for products like so:
match "/products/index.js", :controller => 'products', :action =>
'index', :format => :js
and proceed as normal. What this does in essence is get Rails to skip using the brand-new asset manager system... and go back to the old-fashioned rendering setup. This is probably a good thing as the index.js is rendered per-request and won't be concat'd together with the other javascript and not minified.
//maybe good answer...

Categories

Resources