I am using NodeJS and MongoDB.I have a simple app.You type your data to the textarea,when click submit,it creates a new object in a database.Then if you wanna check certain information in your database,you can type to input an id.It will search in the database for the object with the same id and then it will show you the information on the next page.It works nicely.But what i also need,is that if you will send the JSON POST request to my server,let's say,through POSTMAN,i want it to be displayed not as HTML,but as a JSON object.I guess i need to right a middleware that will check the request first,and if it should be html,it will keep running the code that renders an HTML,and if there is JSON request,then it will do another thing.
That's the code that finds the right object by it's id to show on the webpage:
app.post("/insertedids", function(req,res){
var inputid = req.body.emails;
db.collection('emails').find({"_id": ObjectId(inputid)}).toArray(function(err, foundObject){
if(err){
console.log(err)
} else {
res.render("insertedids",{emailslist: foundObject[0].emails});
};
});
});
And this is the code on the page where it shows the data:
<% include partials/header %>
<div class="centeredlist">
<h1>Emails on this ID </h1>
<ul>
<% emailslist.forEach(function(email){ %>
<li><%=email%></li><br/>
<% });%>
</ul>
</div>
<% include partials/footer %>
So i need that if there is a Json request,it will respond by showing a json objects,not an li's.
P.s inpuid that's the name of my input.
P.s.s i am sorry if i made grammar mistakes :D
Related
I have this code that allows me to get all the posts that the user made in my DB. The problem is that I tried to send that data to the front end (client). But I didn't succeed and I don't know what I'm missing,
The code that extracts the user's info from mongoDB is below. Tthe code is working perfectly, no issue with it,
User.find({}).lean(true).exec((err, users) => {
let userMap = [];
userMap.push({ user: users[i], posts: users[i].posts[j] });
//all the data are stored to userMAP :[{user : xxxxx ,posts : {the posts are here}}]
}
}
}
console.log(userMap);
User.findOne({ userName: req.user.userName }, (error, req_user) => {
console.log(req.user.lastLogin)
let lastSeen = ta.ago(req.user.lastLogin);
//console.log(posts)
res.render('home', { // this part for rendering the homePage and send data
user: req_user,
people: users,
userMap: userMap.reverse()
});
});
What I tried in my client side code is this:
<div class="container">
<% for(var x=0;x<user.posts.length;x++) { %>
<div class="jumbotron">
<div>by
<b>{{ user.posts[x].author }}</b>
on
<small>{{ user.posts[x].createdAt }}</small>
</div>
<div>
<p>{{ user.posts[x].caption }}</p>
</div>
<div class="row">
<button onclick="actOnPost(event);"
data-post-id="{{ this.id }}">Like
</button>
<span id="likes-count-{{ this.id }}">{{ this.likes_count }}</span>
</div>
</div>
<% } %>
For the error part I don't get anything,
this is the image of my stored data in the database
and this is the image of the homepage
The scenario for my code :
1- I'm using a EJS view engine and when the user login in the home.ejs is showing up and in the server side I use the code above to prepare the data that I need to display
2- Everything works perfectly except for displaying the data on the client side home.ejs
3- to call that page from my server I used this statement with the mix of the above code
router.get('/home', (req, res) => {
if (req.user.id) {
console.log(req.user.id)
User.find({}).lean(true).exec((err, users) => {
let userMap = [];
Any help or a better solution for showing data at the client side,
Best Regards,
That's not the syntax to display data in ejs ,try this.See these docs
<%= Outputs the value into the template (HTML escaped)
<% for(var x=0;x<user.posts.length;x++) { %>
<div class="jumbotron">
<div>by
<b><%= user.posts[x].author %></b>
on
<small><%= user.posts[x].createdAt %></small>
</div>
<div>
<p><%= user.posts[x].caption %></p>
</div>
<div class="row">
<button onclick="actOnPost(event);"
data-post-id="<%= this.id %>">Like
</button>
<span id="likes-count-<%= this.id %>"><%= this.likes_count %></span>
</div>
</div>
<% } %>
The source code for the template is being rendered in the browser. This means that the view engine is not parsing it.
The default view engine is Jade, but you aren't using Jade.
Probably you forgot to configure the view engine:
app.set('view engine', 'whatever template engine you are trying to use')
Hi #odegeek what show us so far is how are you getting the data from the database and an idea of how to show it in your view. But we are missing a few pieces of information here. For example:
Which frontend framework are you using if any?
Where are you calling the backend endpoint?
Which view engine are you using?
A typical flow for this scenario would be:
You frontend makes a request to your backend asking for the data
Once the response gets to the browser you do some kind of parsing/mapping to adapt it to your needs
Then you pass it to your view for rendering. Now depending on the frontend framework/view engine you are using. The code to render the data will vary
I hope this can give you a idea of what you need to provide/do .. thanks
I am needing to have 1 page of a website submit data to MongoDB then pull that same data and display it on a different page. I am using node.js, express, Mongoose, and MongoDB.
Currently, I have it so It gets submitted properly to the database, and I can see it with the correct layout, But I cannot seem to get it posted on the page.
How exactly do I go about doing this?
Can someone give a example of code of this?
I am really new to this stuff and still learning.
Thanks!
In the route of the page you want to load, use the Mongoose .find()
method.
You can use {} in the find() method to return all the data, or access
individual data based on the object key find({id:'value'}). Then when you
render the page, just pass in an object to the render, where the key is
what you access in the url page, in my example you would use
(mongs) to access the values within the url page (.ejs, etc). So in
your route definition file:
app.get('/', (req, res) => {
MongModel.find({}, (err, foundMongModel) => {
err ? console.log(err) : res.render('url/route', { mongs: foundMongModel });
});
});
Then if you're using .ejs file, you would need to use <%= %> to access
individual data, and <% %> to use a loop or something.
and use the mongs value. So if you imported all the data from the
database, you could loop through it using
<% mongs.forEach(mong =>{ %>
<div>mong.key<div>
<% }) %>
You can access the keys for each database object like above using
mong.key
I've created a simple blog site, with posts, users and comments.
I'm using - MongoDB, NodeJS and Express with an EJS view.
I've encounterd a problem when I tried to create the comments sections.
I wanted to use JQuery with Ajax requests in order to make the comments section
so the page won't refresh when a user is posting a comment or edting one.
In order to get the comments for each post, I built an api route that look like this - www.domain.com/api/messages/:post_id
this url returns JSON that contains the comments for that post.
I didn't want to expose 'risky' data about the author of the comment so I fillterd the results with the Mongo query.
Now for the problem -
I want to add edit and delete buttons for each comment, that would show up only for the admin and the author of course.
When I use EJS its simple - I wrote something like this -
<% if (user !== null&& (JSON.stringify(user._id) === JSON.stringify(comments[i].author._id)
|| user.is_admin === true)) { %>
put the buttons here...
The thing is, when I'm using JQuery on my main scirpt file, I can't access the user (that's an object that was sent from Nodejs on the backend).
I'm not sure if I should 'send' this object to my js file from the EJS, I think it's not secure and not the right way.
And I can't also keep that EJS code I quoted a few lines ago because when the EJS file loads there are no comments on that page (the XHR request gets them and JQuery puts them on the page).
So I'm really not sure how to move on.
Edit - I think i have a solution: Maybe I should create an array of IDs on the EJS file that would contain the comments that need to have these buttons, and then I would send that array to the JS file somehow?
Thank you!
So I think I managed to overcome this problem, I'll post what I did so hopefully it will help someone in the future.
In the EJS file, I assigned an array that will hold the ID's of the comments that were published by the current user (The user was sent to the EJS file by the nodejd backend).
Then, I copied this array to a script tag variable in the EJS file, By doing that, I can now access it from the main.js file, and add the delete/edit buttons only to comments that have an ID that's in the array.
<% var arr = []; %>
<% for(var i = 0; i < comments.length ; i++){ %>
<% if (user !== null && (JSON.stringify(user._id) === JSON.stringify(comments[i].author._id) || user.is_admin === true)) { %>
<% arr.push(comments[i].comment_id); %> <% } %>
<% } %>
<script>
var exported_array = <%- JSON.stringify(arr) %>
</script>
Send the user and all comments to the main EJS file.
app.get('/', function (req, res) {
res.render('index', {
comments: [{ ... }, { ... }, { ... }],
user: { ... }
});
});
The comments can be rendered by including a EJS partial comment.ejs from the folder partials in the main EJS file.
<% comments.forEach(function(comment){ %>
<% include partials/comment %>
<% }) %>
In that partial you render the comment and buttons. The comment is past through to the include. The user already lives on the main EJS template.
<div class="comment-container" data-commentid="comment._id">
<p><% comment.content %></p>
<% if (user !== null&& (JSON.stringify(user._id) === JSON.stringify(comment.author._id) || user.is_admin === true)) { %>
<button class="button_delete" data-commentid="<% comments_id %>">delete</button>
<% } %>
</div>
Then create a route in your API like www.domain.com/api/messages/delete/:post_id.
app.get('/messages/delete/:post_id', function(req, res){
// logged on user lives on the server
// check if user may delete comments
// delete comment
// send result
res.send(true);
});
When you click the button use jQuery to send that id from the data attribute of the button to the server/api and from there I would Identify the user that's logged on. If the logged on user is authorized delete it and send back the result. If everything is okay use jQuery to delete the div containing the whole message.
$('.button_delete').click(function(){
// retrieve id from data attribute here
var commentId = $(this).data("commentid");
$.get('www.domain.com/api/messages/delete/' + commentId, {}, function(result){
if(result) {
// delete comment container from html using commentId or refresh
}
});
});
I am using the FileStack API and the file picker gem (https://github.com/Ink/filepicker-rails). I have an Attachment model that has a :title as a string. When a file is uploaded, the URL from the FilePicker API is stored as the :title. But the gem has a onchange method that returns an event variable as a JSON object that contains attributes of the file. I use JavaScript to access those attributes but I want to find a way in Rails to store those attributes, accessed via JavaScript, in a Model so that I can access it through the rest of the Rails app.
<%= filepicker_js_include_tag %>
<%= simple_form_for(#attachment) do |f| %>
<%= f.filepicker_field :title, onchange: 'onUpload(event)' %>
<%= f.submit %>
<% end %>
<script>
function onUpload(event) {
console.log(event);
var name = event.fpfile.filename;
console.log(name);
}
</script>
Update:
So after looking into your solution and googling around I am using ajax to send the data via routes to the controller. Below is my updated Javascript as well as the route and controller. When I render and inspect the #foo instance variable it is nil. So my data isn't getting passed properly. Furthermore, this whole process from the firing of the Javascript function to displaying the index view is now very very slow. I think I have the right idea after viewing your solution and doing more digging but I'm missing something and/or overcomplicating this. Any advice would be much appreciated.
<script>
function onUpload(event) {
var name = event.fpfile.filename;
jQuery.ajax({
data : { data_value: event },
type: 'post',
url: "/attachment/index"
});
}
</script>
Route
post 'attachments/' => 'attachment#index'
Controller
def index
#attachments = Attachment.all
#foo = params[:data_value]
end
View (returns nil)
<%= raise #foo.inspect %>
If you're using Postgres 9.3 or above you should consider using the hstore module and creating a JSON column. In a migration you can do:
add_column :your_model, :your_attribute, :json
And then you can just update YourModel.your_attribute => {'your': 'JSON here'}
Docs here: http://edgeguides.rubyonrails.org/active_record_postgresql.html#json
If you're using MySQL it's tricky, but doable. You have to create a text column and save the JSON as a string, and parse it every time you interact with it. Postgres is definitely better at handling JSON. I realize that this answer relies on an assumption, so if you're not using one of the two data stores mentioned, let me know and I'll pull it down.
I am trying to connect to the Plaid api using Ruby. But I am trying to connect it using <script> tag. I have successfully connected to their api and there is a json object returned in the response as I can see it in browser's console.
But I am unable to get it in my code. My code is
<%= form_for :user, method: :get, :html => { :id => "link-form-id" } do |f| %>
<% end %>
<script
src="https://cdn.plaid.com/link/stable/link-initialize.js"
data-client-name="Mandeep"
data-client-id="**********"
data-form-id="link-form-id"
data-key="***********"
data-product="auth"
data-env="tartan">
</script>
This code returns json object in url as well. I dont understand how can I get it from <script> tag.
I have searched all over the web but couldn't get any useful stuff. Can you please help me to find this out. Your help would be appreciated. Thanks
Since the method of the form is 'GET' you'll need to parse the query string to retrieve the Plaid Link public_token (so you will want to look for the 'public_token' field in the querystring).