Deleting from Database Using Jquery Ajax Request in Nodejs - html

I am working on a Nodejs project and currently working on delete requests to delete items (recipes) stored in a database. I have looked at other similar posts and around Google but can't seem to pinpoint the cause of my problem. I keep getting the following error:
And, I am unsure why. What I believe I am doing wrong is retrieving the Recipe _id incorrectly, but am not completely sure. The link to this project repo is: https://github.com/halsheik/RecipeWarehouse.git. Below, I have pasted the relevant portions of my code that I have added (not yet uploaded to repo). I'd appreciate any assistance.
$(document).ready(function(){
$(".secondaryContainer").hover(function(){
$(this).find(".deleteButton").fadeIn();
}, function(){
$(this).find(".deleteButton").hide();
});
$('.deleteButton').on('click', function(event){
$target = $(event.target);
const id = $target.attr('data-id');
$.ajax({
type:'DELETE',
url: 'article/' + id,
success: function(res){
window.location.href='/articles/myRecipes'
},
error: function(err){
console.log(err);
}
});
});
});
// Delete recipe
router.delete('/:id', function(req, res){
const query = {_id: req.params.id}
Recipe.remove(query, function(err){
if(err){
console.log(err);
throw err;
}
res.send('Success');
});
});
<%- include('../_partial/_header'); -%>
<!-- Container for all of a user's recipes -->
<div id="recipesContainer">
<div id="myRecipesContainer">
<label id="myRecipesLabel">My Recipes</label>
<!-- Button to Create a New Recipe -->
+ Create New Recipe
</div>
<!-- Displays each individual recipe (The name and image) -->
<div id="allRecipes">
<% if(recipes.length > 0) { %>
<% recipes.forEach(function(recipe){ %>
<% if(recipe.author == user._id){ %>
<div class="secondaryContainer">
<span class="deleteButton"><i class="fa fa-trash-o" data-id="<%= recipe._id %>" aria-hidden="true"></i></span>
<div class="recipeContainerIndv">
<img src="/uploads/<%= recipe.recipeImageFileName %>"/>
<%= recipe.recipeName %>
</div>
</div>
<% } %>
<% }); %>
<% } else { %>
<div id="noRecipesContainer">
<a id="noRecipes">You Currently Have No Recipes!</a>
</div>
<% } %>
</div>
</div>
<%- include('../_partial/_footer'); -%>

I can't understand the objective of the following code:
$('.deleteButton').on('click', function(e){
$target = $(e.target);
const id = $target.attr('data-id');
//...
When click event is triggered on deleteButton, the event's target is just the <span.deleteButton> itself which has no 'data-id' attribute.
In this way you can get 'id':
$('.deleteButton').on('click', function(){
const id = $(this).parent().attr('data-id');
//...

Related

How to change the page diaplayed on the same route based on whether the person is logged in or not? I'm using node.js express auth0

If someone visits the site , they are going to be directed towards '/' which will display index page
This page has login and signup options.
server.js--
const express = require("express");
const ejs = require('ejs');
const app = express();
const { requiresAuth } = require('express-openid-connect');
const { auth } = require('express-openid-connect');
app.get('/', (req, res) => {
res.render('pages/index');
});
however , if the person has logged in and wants to view the index page again I want to remove those login and signup links.
these links are coded in navigation bar in html, ejs.
index.ejs--
<%- include('../partials/head.ejs') %>
<body>
<%- include('../partials/navbar.ejs') %>
<form action="/" method="POST">
<button class="btn btn-light btn-lg btn-block addPG"> Add New...</button>
</form>
<%- include('../partials/footer.ejs') %>
</body>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</html>
I wrote a new index page for those who have logged in but I cant figure a way to do so.
Is my approach right or is there a better way to implement the stuff that I desire.
How I did it in my navbar was with if statements, Below is a snippet of how I have my ejs file
<%if (user && user.role==2) { %>
<li class="treeview">
<a href="#">
<i data-feather="user-check"></i>
<span>Admin</span>
<span class="pull-right-container">
<i class="fa fa-angle-right pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li><i class="icon-Commit"><span class="path1"></span><span class="path2"></span></i>Users</li>
<li><i class="icon-Commit"><span class="path1"></span><span class="path2"></span></i>Recent Devices</li>
</ul>
</li>
<% } %>
<% } %>
<%if (!user) { %>
<li>
<a href="/signin">
<i data-feather="log-in"></i>
<span>Signin</span>
</a>
</li>
<% } %>
That just checks if there is a user, and you can update your HTML to show stuff based on roles and such.

How to Get The Value From a Option That Got Selected, Using The select_tag helper

How to get the value of the option that got selected on the < select > that was build using the select_tag helper in Ruby on Rails.
The code goes like this:
<%= f.label "Favorite Team" %>
<%= select_tag :fav_league, options_for_LEAGUEs, :onchange => 'check1()' %>
I want this value because, depending on which option was selected, a different < select > will appear to the user.
Example: There is a form and I want to know what is the name of the county that this user lives in, so I create a first < select > where the user select the State. Depending on what option he choosed, a different group of options will appear on the second < select > ( where he chooses his county, and this is what is going to be submit with the form, without the State initials.) The same occurs on my web app, but with National Leagues and Teams ( that's why options_for_LEAGUEs ( an array with the name of every League ) )
Ps: I want it in Ruby, if it can be moved to javascript it would be better, but you have to explain how
The code goes like this:
<%= f.label "Favorite Team" %>
<%= select_tag :fav_league, options_for_LEAGUEs, :onchange => 'check1()' %>
How to get the value of the option that got selected on the <select>
...if it can be moved to javascript it would be better,
In your select_tag(), you specified a function check1() for the onchange attribute. A function that is specified for an onchange attribute is a javascript function, and when the user makes a change to the select, the web browser will look around for a javascript function called check1() to execute. Therefore, you need to define a javascript function called check1() in a js file. In rails, you put js files in the app/assets/javascripts directory. Here is an example:
app/assets/javascripts/users.js:
function check1(select) {
var options = select.options;
var selected_index = select.selectedIndex;
var selected_val = options[selected_index].value;
var selected_text = options[selected_index].text;
//Now that you have the selected option, do something with it:
alert("val: " + selected_val + ", text: " + selected_text);
//Or, maybe send the data to the server and your rails app:
var post_data = {
"fav_league": {"val": selected.val(), "text": selected.text()}
};
$.post('/users/dostuff', post_data, function(response_data) {
$("#result").html(response_data);
});
}
Note the use of this in the onclick below:
app/views/users/index.html:
<h1>Users#index</h1>
<p>Find me in app/views/users/index.html.erb</p>
<% options_for_LEAGUEs = [
["league1", 1],
["league2", 2],
["league3", 3]
]
%>
<div>
<%=
select_tag(
:fav_league,
options_for_select(options_for_LEAGUEs),
onclick: 'check1(this)'
)
%>
</div>
<div id="result">
</div>
app/controllers/users_controller.rb:
class UsersController < ApplicationController
def index
end
def dostuff
if request.xhr? #If this is an incoming ajax request...
val = params['fav_league']['val']
text = params['fav_league']['text']
render plain: "You sent me: #{val}, #{text}"
end
#Otherwise, by default rails renders app/views/users/dostuff.html.erb
end
end
Or, you can forgo the inline onclick in the html, and use jquery to install the onclick handler:
$(document).ready(function() {
$("#fav_league").on("change", function() {
var selected = $(this).find("option").filter(":selected");
//Now that you have the selected option, do something with it:
alert(
"val = " + selected.val() + ", text = " + selected.text()
);
//Or, maybe send the data to the server and your rails app:
var post_data = {
"fav_league": {"val": selected.val(), "text": selected.text()}
};
$.post('/users/dostuff', post_data, function(response_data) {
$("#result").html(response_data);
});
});
});
Response to comment:
It's probably easier to dynamically create a single team select based on the league choice, then let the user submit the form to send the team choice to the server. Here's an example:
You can use an empty <div> with a data attribute in your view, and use rails to insert the team names into the data attribute, which will allow javascript executing in the browser to retrieve those names from the html:
<%= content_tag :div, id: "teams_div", data: {teams: #teams_for_league} do %>
<% end %>
app/views/users/index.html.erb:
<h1>Users#index</h1>
<p>Find me in app/views/users/index.html.erb</p>
<div>
<%= form_for #user, url: {action: 'dostuff', method: "post"} do |f| %>
<%= f.label "Favorite Team" %>
<%= select_tag(
:fav_league,
"<option disabled selected>--select league--</option>#{options_for_select(#leagues)}".html_safe
)
%>
<%= content_tag :div, id: "teams_div", data: {teams: #teams_for_league} do %>
<% end %>
<%= f.submit('Submit') %>
<% end %>
</div>
Note that if you don't call html_safe() on the options string, the options may not get created correctly. options_for_select() will take care of that for you, but if you want to add custom styles to an option and manually add it to the options string, then you need to call html_safe().
app/controllers/users_controller.rb:
class UsersController < ApplicationController
def index
#user = User.find(1)
#leagues = [
["league1"],
["league2"],
["league3"],
]
#teams_for_league = {
league1: ["team1", "team2"],
league2: ["team3", "team4"],
league3: ["team5", "team6", "team7"],
}
end
def dostuff
puts "-" * 10
p params
puts "-" * 10
team_choice = params[:team_select]
if team_choice
puts "**** The user chose: #{team_choice} *****"
else #The user failed to select a team...
redirect_to action: :index
end
end
end
app/assets/javascripts/users.js:
$(document).ready(function() {
$("#fav_league").on("change", function() {
var $selected = $(this).find("option").filter(":selected");
var league_choice = $selected.text();
var $teams_div = $('#teams_div');
var teams_arr = $teams_div.data("teams")[league_choice];
var team_name,
$new_select;
$teams_div.empty();
$new_select = $(
'<select>',
{name: "team_select"}
).appendTo($teams_div);
$new_select.append(
$("<option>",
{disabled: true, selected: true}
).text("--select team--")
);
for (team_name of teams_arr) {
$new_select.append(
$("<option>").text(team_name).attr('value', team_name)
);
};
});
});
If you choose a team, then submit the form, you'll see the following output in the window where your server is running:
...
...
----------
{"utf8"=>"✓", "_method"=>"patch",
"authenticity_token"=>"By2pZpUTxK2JZHBHYA7C4tryFTx2btBLnoGjdYpiOxPeHaHcLAO0VJue64HlTLGVLHzkZkdj4SRqAAt85Mn32A==",
"fav_league"=>"2", "team_select"=>"team4", "commit"=>"Submit",
"method"=>"post", "controller"=>"users", "action"=>"dostuff"}
----------
**** The user chose: team4 *****
Rendered users/dostuff.html.erb within layouts/application (0.0ms)
Completed 200 OK in 20ms (Views: 19.2ms | ActiveRecord: 0.0ms)

EJS in HTML not working

is this a correct syntax for EJS technology in HTML ? The "flash object" is send from controller . Here it is my "log in" action in Controller and HTML code. I want a peace of HTML is executed base on the content of "flash object". But it doesn't work.This is controller in back end:
login: function(req, res){
var x = new LdapService();
x.login(req.body.userid, req.body.password, function(isAuth){
if(isAuth ){
res.send('successful login');
}
else{
res.view('login/index', {locals: {flash: req.flash('error', 'Wrong Credentials')}}) ;
}
});
},
=============================================
Here it is the HTML code in front end.
<% if (req.flash('error')!=''){ %>
<p>Hi</p>
<p><%- (req.flash('error')) %></p>
<div class="box-body">
<div class="alert alert-danger alert-dismissable">
<i class="fa fa-ban"></i>
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
<b>Alert!</b> Wrong
</div>
</div>
<% } %>
Once you access the flash object using req.flash, its value is cleared. So the conditional test will clear the flash object.
The value is also stored in the session, so I test the session directly before displaying the flash value.
<% if(req.session.flash && req.session.flash.error){ %>
<div class="row form-row m-l-20 m-r-20 xs-m-l-10 xs-m-r-10">
<div class="alert alert-error">
<button class="close" data-dismiss="alert"></button>
<%- req.flash('error') %>
</div>
</div>
<% }%>
It's not entirely clear why you need to use flash messages in this case, since you're setting the message and displaying it in the same request. Flash messages are more appropriate when you're setting a message and then redirecting, because the code before the redirect doesn't have the opportunity to set the view locals directly. You could just do:
res.view('login/index', {locals: {flash: {'error':'Wrong Credentials'}}});
and in your template:
<% if((flash = {} || flash) && flash.error){ %>
<div class="row form-row m-l-20 m-r-20 xs-m-l-10 xs-m-r-10">
<div class="alert alert-error">
<button class="close" data-dismiss="alert"></button>
<%- flash.error %>
</div>
</div>
<% }%>
If you were redirecting from another view, then you could use flash messages and keep the same template. In the action you're redirecting from, you'd set a flash message:
req.flash('error', 'my error message');
res.redirect('/someOtherLoginRoute');
and in the action you redirected TO, do:
res.view("login/index", {locals: {flash: req.flash()}});
It's kind of a contrived example, but there you have it.

sending var in html from view backbone

Hi I am learning backbone.js and as a part of a project I want to send a variable from my view.js file in Backbone to the associated template(.html). How should i do it?
Currently I try to do the following but fail:
In View.js:
$( ".result" ).html( displayChoice );
In html template:
<% if(!displayChoice.localeCompare("true")) { %>
<div class="name" id="choices"><%- choices[i].choice %></div>
<% } %>
Please tell me what is wrong in this approach.

Update HTML tag in the view with Ajax dilemma

I'm new to this and have no idea how it must work.
I have a partial view in a foreach in my view that lists all news comments for that news article.
I have a textarea with a post button where the user can submit further comments on this news article.
The new news article must be appended to the list, without doing a location.reload. I was told do use AJAX, not JSON.
Here's my controller:
[HttpGet]
[NoCache]
public ActionResult SetCommentOnNews(int newsId, string newsComment) ??
{
var currentUser = ZincService.GetUserForId(CurrentUser.UserId);
ZincService.NewsService.SetCommentOnNews(newsId, newsComment, currentUser.UserId);
return Json(new { success = true }, JsonRequestBehavior.AllowGet); ??
}
<div class="news-comment-content" id="news-comment-content">
<% if (Model.Results != null) {
foreach (var newsItem in Model.Results.NewsComments) %>
<% { %>
<% Html.RenderPartial("~/Views/Home/SetCommentOnNews.ascx", newsItem); %>
<% } %>
</div>
my partial:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Zinc.Web.Areas.News.ViewModels.Home.NewsCommentsViewModel>" %> //this also not right
<div class="news-post-list-item">
<div class="news-post-user-info-wrapper">
<div class="avatar">
<img width="52" height="52" alt="Avatar" src="/ThemeFiles/Base/images/User/user-avatar.png"/>
</div>
<div class="who-and-when-box">
<%: newsItem.CommentDate %>
<br />
<br />
<%: ViewBag.UserName %>
</div>
<div class="news-comment"><%: newsItem.NewsComment %></div>
<div class="clear"></div>
</div>
<div class="clear"></div>
</div>
<div class="header">
<h3>
Leave a comment
</h3>
</div>
<div>
<textarea id="textareaforreply" rows="3" cols="160"></textarea>
</div>
<div>
Post
</div>
<script type="text/javascript">
function PostNewsComment(newsId) {
$("post-button").click(function () {
var jqxhr = $.getJSON("<%= //Url.Action("SetCommentOnNews", "Home", new { area = "News" }) %>?newsId=" + newsId + "&newsComment=" + $("#textareaforreply").text(), function (data) {
if (data.success) {
alert($("#textareaforreply").text());
$('#news-comment').append($("#textareaforreply").text());
}
});
}
</script>
The above JS is what I have and must inject HTML in to the list using AJAX?
I have NO idea how to do this. Can some one help please?
Thanks
To inject HTML into a list using AJAX I would use Knockoutjs with templates instead of partial views. Knockout can be used to render the information in the browser. Views are for rendering server side, which does not jibe well with AJAX.
What do you mean when you say, "I was told do use AJAX, not JSON". AJAX uses JSON as a method for serializing the data that is sent over the network. Are you referring to the JQuery methods ajax versus getJSON? getJSON is just a wrapper around the ajax method that configures it specifically to retrieve JSON using the HTTP GET verb. Either will work fine, but ajax does give you more control in configuring the request.