Express req.param deprecated syntax - javascript

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

Related

Modify URL on copy (-paste)

I need to modify the url on copy from an angular project.
When the user selects URL and copy (like ctrl+c), it is
page/item/123
I need to modify that to
page/item?id=123
How can I do that?
Reason: I could not make the web.config work to pass the full path (item/123), so angular cannot parse what is not there.
However, I can make item?id=.... work, so it opens "item" and there I can get the query parameter.
Added: in the comments it was suggested to do it one way/the right way only and I agree - but I am here because my original problem cannot be solved: web.config - forward full path with parameter
How to make rules work with parameters and pass the full path for parsing
Here's how it can be done:
html
<div (copy)="handleCopy($event)">page/item/1234</div>
ts
handleCopy(event: ClipboardEvent) {
event.clipboardData.setData('text/plain',
document.getSelection().toString().replace(/\/(?=[^\/]*$)/, "?id="));
event.preventDefault();
}

HapiJS JSON Formatting

I'm writing a small CRUD app and I'd like to have some formatting on the JSON responses I'm getting (mostly for ease of reading).
Is there a setting I'm missing?
I wouldn't recommend forcing your API consumers to have a pretty JSON format. If you want to see the JSON in a nice format I'd recommend installing the Chrome JSON Formatter Plugin or using something like Postman.
After digging some more through the API documentation (RTFM, right?), I found the actual setting that enables the behavior I was looking for.
server.connection({
port: 3000,
routes: {
json: {
space: 4
}
}
});
While the Chrome extension is a good answer, this will work with other browsers.
If you want to apply the pretty JSON format dynamically, based on a query param or header, you can use the following code (tested in v20.2.2):
srv.ext('onPreResponse', (req : Request, h : ResponseToolkit) => {
const { response } : any = req;
if (req.query._pretty) {
response.spaces(2).takeover();
}
return h.continue;
});
If you call whatever method with a paramlike _prettyfor instance:
curl -XGET http://localhost:3003/api/foo?_pretty=1
You'll get a response like:
{
"id": 1253,
"name": "Everything OK"
}
But if you don't add the param:
curl -XGET http://localhost:3003/api/foo
Then the JSON output is collapsed:
{"id":1253,"name":"Everything OK"}
The name of the parameter could be whatever thing that won't be used in your app, so add a prefix like _ or whatever else, you can also use a specific header instead a query param if you prefer.

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

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).

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.

Passing objects from NodeJS to client and then into KnockoutJS viewmodel

So thanks to SO I can pass an object from node to the client, but then getting it into a knockout view model is a bit awkward. These are the steps I have so far (I've included links to the relevant lines as they appear in my github project. Thought the context might help.):
Apply JSON.stringify and pass to the jade file
recipeJSON: JSON.stringify(recipe);
Wrap this in a function in a header script that just parses the JSON and returns the result
script
function getRecipeObject() {
var r = '!{recipeJSON}';
return JSON.parse(r);
}
Call this function and pass the result to a view model constructor
self.recipe = ko.observable(new Recipe(getRecipeObject()));
This works but is there a better way?
Question clarification (Edit): I feel step 2 shouldn't be necessary. Is there a way to directly pass the JSON from node to the Recipe() constructor, without the getRecipeObject() acting as an intermediate step? I tried passing recipeJSON in directly like so
self.recipe = ko.observable(JSON.parse('!{recipeJSON}'));
That doesn't work I think because its not a jade template and has no access to the variable.
According to the answer to this question rendering data into scripts is bad practice and I should instead make an XHR call on page load instead.
Edit
I just saw you linked a github repo! So you're already familiar with most of this...you even have an endpoint set up at /recipe/:id/view, so now I'm really confused...what isn't working out for you? Just the last step of deserialization using ko.utils.*?
Sorry about all the exposition -- I thought this was way more rudimentary than it actually was; I hope no offense taken there!
You really don't want to return a script to execute -- instead, treat this as a DTO: an object that just stores data (no behaviors). An example would be:
{
recipeID: 12,
reviewIDs: [42, 12, 55, 31],
rating: 4.2
recipeName: "A super tasty pie!"
}
This object (representation) is a projection -- a simplified version of the full data stored in the database.
The next step is to create an endpoint to access that data on the server. Let's assume you're using Express:
var app = express();
app.get('/recipes/:recipeID', function(req, res) {
var recipeID = req.params.recipeID;
// It would be cool if this existed, huh?
getRecipeAsync(recipeID, function(recipe) {
res.status(200).json(recipe);
});
});
If you send a GET request to your (hypothetical) application (let's say it's https://localhost:8080/recipes/12), you'll get json representing the (admittedly imaginary) recipe with ID 12.
You can accomplish getting the JSON with jQuery (or any other library that makes XHR nice and pretty)
var recipeID = 12;
$.ajax({
url: "/recipes/" + recipeID,
type: "GET"
}).then(function(recipe) {
console.log("Hey! I got the recipe: %O", recipe);
// Note: you might need to use ko.utils.fromJS(recipe) if the returned
// data is JSON that ISN'T deserialized into an object
var recipeObservable = ko.utils.fromJS(recipe);
});
That's about everything you need to know. Obviously, the devil's in the details, but that's basic idea; let me know if that helps!

Categories

Resources