//user.js
I created the following model Schema with mongoose:
var UserSchema = new mongoose.Schema ({
username: String,
password: String,
ThisSetup: [{name: String, quote: String}]
});
module.exports = mongoose.model("User", UserSchema);
In the mongoDB I can see in the terminal, that this concept is working fine, but if I try to display name property with ejs the following way, ids are displayed, but the names not:
//userid.ejs
<% User.forEach(function(User){ %>
<div class="row">
<p><%= User._id %> <%= User.ThisSetup.name%></p>
</div>
<% }); %
This way I see in the browser the names and the quotes too:
<%= User.ThisSetup %>
How can I reach just the names?
Thank you for in advance
Thanks!
The solution:
<%= User.thisSetup[0].name %>
Related
const methodOverride = require("method-override");
app.use(methodOverride("_method"));
app.delete("/comments/:id", (req, res) => {
const { id } = req.params;
comments = comments.filter((c) => c.id !== id);
res.redirect("/comments");
});
<h1>Comment id: <%= comment.id %></h1>
<h2><%= comment.comment %> - <%=comment.username %></h2>
Back to index
Edit Comment
Edit Comment
<form method="POST" action="/comments/ <%= comment.id %>?_method=DELETE">
<button>Delete</button>
</form>
Building a simple CRUD app and the ?_method=DELETE is not working for some reason. I am able to do everything else, however when I try to delete there is no error. The page just redirects/refreshes. Any help would be appreciated.
model named Field.js
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/SuperchainV1', {
useNewUrlParser: true });
mongoose.set('useNewUrlParser', true);
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
const db = mongoose.connection;
const FieldSchema = mongoose.Schema({
productID: {
type: String
},
productName:{
type: String
},
fieldLocation: {
type: String
},
farmerName: {
type: String
},
farmerMobile: {
type: String
},
farmerNid: {
type: String
},
date: {
type: Date,
default: Date.now
}
});
const Field = mongoose.model('Field', FieldSchema);
module.exports = Field;
routes index.js
router.get('/dashboard', ensureAuthenticated, (req, res) => {
let field = Field.find({})
.sort({date:'desc'}).exec( (err, field) => {
res.render('dashboard', field);
});
})
dashboard.ejs where i want to display data after fetching
<div class="jumbotron">
<p class="lead">
<% field.productID %>
<% field.productName %>
<% field.fieldLocation %>
<% field.farmerName %>
<% field.farmerNumber %>
<% field.farmerNid %>
</p>
</div>
errors i get "field is not defined"
I want to fetch data from collections fields and display all the data into a ejs page named dashboard i tried this but always get the error field is not defined.
You need to use for loop in ejs template
<% for(var i=0; i < field.length; i++) { %>
<div class="jumbotron">
<p class="lead">
<%= field[i].productID %>
<%= field[i].productName %>
<%= field[i].fieldLocation %>
<%= field[i].farmerName %>
<%= field[i].farmerNumber %>
<%= field[i].farmerNid %>
</p>
</div>
<% } %>
I'm using ejs to try to output a username from req.user in a node express app, but it doesn't seem to be working.
This is where my username and password come in:
app.get('/', function(req, res) {
res.render('index', {
isAuthenticated: req.isAuthenticated(),
user: req.user
});
console.log("req.user:", req.user);
});
At this point, I can see req.user in terminal displayed like this:
req.user: [ { _id: 5890f8a97ef995525d4b78cd,
username: 'dave',
password: 'somepassword',
__v: 0 } ]
This is what I have in index.ejs:
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<head>
<body>
<% if (!isAuthenticated) { %>
Log in here
<% } else { %>
Hello, <%= user.username %>!
Log out
<% } %>
</body>
</html>
And this is the login form:
<!DOCTYPE html>
<html>
<head>
<title>Passport</title>
<head>
<body>
<form action="" method="post">
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<input type="submit" value="Login">
</form>
</body>
</html>
I initially had this in my index.ejs, but still did not output username.
Hello, <%= user.name %>!
Would appreciate any help.
Based on what your terminal displayed, it looks like req.user is an array containing objects, which means that you would need to access one of the elements in the array before accessing the object's properties.
Therefore <%= user.username %> would be <%= user[0].username %>:
<% if (!isAuthenticated) { %>
Log in here
<% } else { %>
Hello, <%= user[0].username %>!
Log out
<% } %>
Or you could just update the web service to pass in the first element in the user array:
res.render('index', {
isAuthenticated: req.isAuthenticated(),
user: req.user[0]
});
<% if (!isAuthenticated) { %>
Log in here
<% } else { %>
Hello, <%= user.username %>!
Log out
<% } %>
You may also want to check if the user array contains any elements to prevent any errors from being thrown if it doesn't:
res.render('index', {
isAuthenticated: req.isAuthenticated(),
user: (req.user && req.user.length) ? req.user[0] : {}
});
How can we use f.select tag for collection of static hash values
class ReceiptPrinter
RECEIPT_PRINTER_TYPES ={
0=> "Normal",
1=> "Dot Matrix",
2=> "Thermal",
}
def initialize(options={})
#receipt_printer_type=options[:receipt_printer_type] || DEFAULT_VALUES[:ReceiptPrinterType]
#receipt_printer_header_height=options[:receipt_printer_header_height]|| DEFAULT_VALUES[:ReceiptPrinterHeaderHeight]
#receipt_printer_header_type=options[:receipt_printer_header_type]|| DEFAULT_VALUES[:ReceiptPrinterHeaderType]
#receipt_printer_template=options[:receipt_printer_template]|| DEFAULT_VALUES[:ReceiptPrinterTemplate]
# define_methods()
end
end
In my view page i used select option
<% form_for #receipt_printer, :url => { :action => "fees_receipt_settings" } do |f| %>
<%= f.select("receipt_printer_template", #settings.map{| item| [item[0],item[1].to_i]},{},{:onchange => "set_template(this.value)"} ) %>
<% end %>
I am getting error wrong number of arguments
You can try with rails's options_for_select,
<%= f.select :receipt_printer_template",options_for_select(#settings.map{ |item| [item[0], item[1]],{},{:onchange => "set_template(this.value)"} ) %>
Here is the reference
ANSWER.
Since #settings is just a simple hash, you don't have to use map. The select form helper should look like:
<%= f.select :receipt_printer_template, #settings, {}, {onchange: "set_template(this.value)"} %>
SUGGESTED REFACTOR
If you are adamant on using map, I would suggest to refactor the code a little to prevent your view from being flooded with app logic, something like:
# app/helpers/receipt_helper.rb
def settings_for_select
#settings.map{ |item| [item[0],item[1].to_i] }
end
# your form view
<%= f.select :receipt_printer_template, settings_for_select, {}, {onchange: "set_template(this.value)"} %>
Should help a little already, also notice the use of the new hash syntax, it provides a cleaner API to work with.
I've got a web page that creates an "Activity." Using simple form, the user fills in some basic information about the activity:
#new.html.erb
<%= simple_form_for #activity do |f| %>
<%= f.input :name, label: "Activity name", input_html: { id: "create_activity_name_field" }, hint: "At least 7 characters" %>
<%= f.input :type, label: "Activity type", input_html: { id: "create_activity_type_field" }, as: :select, :include_blank => false, collection: Activity.types.keys.to_a %>
<%= f.input :date_field, input_html: { id: "create_activity_date_field" }, as: :string %>
<%= f.input :time_field, input_html: { id: "create_activity_time_field" }, as: :string %>
<% f.button :submit, :class => "btn btn-primary" -%>
<% end %>
However, I am also using MapBox to display a map. The user will click the points on the map to make a route for the activity. When the user is done drawing the route, I can then extract GeoJSON data for this route.
I would like to use javascript to POST the GeoJSON data with the form data. On the backend, I'll have rails convert the GeoJSON to a KML file, and use Paperclip to upload it to Amazon S3. The rest of the data can be saved, and Paperclip will give me a URL to the KML file which I can associate with the activity.
I'm a Rails noob, and I can't figure out how to do this nor track down anything to get me over this hurdle. I considered using javascript's FormData. I was very attracted to this approach, because implementation looks so simple, but apparently it can only really handle key/value pairs, not complex nested JSON data.
Any suggestions or strategies greatly appreciated. And greatly appreciated++ if anyone can give detailed answers because, like I said, I'm a few weeks fresh to rails and web development.
What you probably want to do here is to prevent the default behavior of your form using in JS :
$('form').submit(function(e) {
e.preventDefault();
var form = $('form');
var form_data_json = JSON.stringify(form.serializeArray());
form_plus_geojson = form_data_json.concat(Geojson);
Grab your data in JS ( this should be easy but you dont really say how do you extract the data from mapbox ).
Then send back the data via AJAX ( don't forget validation on either end )
if (my_data_is_not_good/empty/whatever) {
console.log('nop')
} else {
$.ajax({
type: 'post',
url: Yourcontrollerpostaction,
data: form_plus_geojson,
dataType: "JSON",
Once the data has been sent you want to resume the normal form submission post behavior and submit the form.
complete: function() {
this.off('submit');
this.submit();
}
});
}
});
Then you just need to parse the data in your controler.
def post_controller
if request.xhr?
my_hash = JSON.parse(params[:mydata])
else
normal post behavior
end
end
Everything is quick pseudocode you might have to fix some stuff as i haven't tested it but it should work.
Obviously now that we are doing everything in ajax you don't need the complet function call back and can remove that part.
Kudos to #jDay for pointing me in the right direction -- specifically with concatenating the JSON data. However, I couldn't get his specific solution to work on my app, and I went trying another method which, in my view, was a little more straightforward.
I used the Rails simple_form_for gem to make the form, specifying a remote post call:
#new.html.erb
<%= simple_form_for #activity, :url => '/activities', :method => :post, :remote => true, html: {id: :activity_create_form, "data-type" => :json} do |f| %>
<%= f.input :name, label: "Activity name", input_html: { id: "create_activity_name_field" }, hint: "At least 7 characters" %>
<%= f.input :type, label: "Activity type", input_html: { id: "create_activity_type_field" }, as: :select, :include_blank => false, collection: Activity.types.keys.to_a %>
<%= f.input :date_field, input_html: { id: "create_activity_date_field" }, as: :string %>
<%= f.input :time_field, input_html: { id: "create_activity_time_field" }, as: :string %>
<%= f.button :submit, :class => "btn btn-primary", input_html: {id: "create_activity_submit_btn"} -%>
<% end %>
Then I used jQuery to to hijack the form submit button and append an invisible form element bearing the GeoJSON data. The data, however, had to be stringified so it could be sent:
#activity_new.js
$("form").submit( function (e) {
e.preventDefault();
$('<input />')
.attr('type', 'hidden')
.attr('name', 'routeGeoJson')
.attr('value', JSON.stringify(polyline.toGeoJSON()))
.appendTo(this);
return true;
});
(Here, "polyline" is a Leaflet L.polyline object that I used to draw on the map.)
In the controller, you'll get params like this:
{"utf8"=>"✓", "activity"=>{"name"=>"A jaunt in the woods", "type"=>"walk",
"date_field"=>"2015-09-08", "time_field"=>"07:00"},
"routeGeoJson"=>"{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"LineString\",\"coordinates\":[[-118.38855654001236,33.95361274499209],[-118.36624056100845,33.97681937760982]]}}",
"commit"=>"Create Activity", "controller"=>"activities",
"action"=>"create"}
Since the "routeGeoJson" data is still in string form, I reassembled the GeoJSON data by parsing it using the JSON gem (which I believe is included by default in Rails 4):
def create
geojson = JSON.parse(params[:routeGeoJson])
# do something...
end
And you get your GeoJSON hash:
{"type"=>"Feature", "properties"=>{},
"geometry"=>{"type"=>"LineString",
"coordinates"=>[[-118.42014223337173, 33.98407904797006],
[-118.37825685739517, 33.956175751601826]]}}