How to add DELETE operation to a button Node.js - html

I want to add a delete functionality to a button that's part of a card which is encapsulated in a form this is as far I got:
<form class="form-events" action="/delete" method="post">
<% events.forEach( function (event) { %>
<div class="card col-lg-3" style="width: 18rem;">
<img class="card-img-top">
<div class="card-body">
<h5 class="card-title"><%= event.title %></h5>
<p class="card-text"><%= event.description %></p>
<p class="card-text"><%= event.date %> </p>
<p class="card-text"><%= event.capacity %></p>
Update
<button onclick="this.form.submit()" value="<%= event._id %> " name="deletebtn" class="btn btn-danger">Delete</button>
</div>
</div>
<% }); %>
</form>
And this is the route for it:
// Delete an event
app.post("/delete", function (req, res) {
const deletedItemId = req.body.deletebtn;
Event.findByIdAndRemove(deletedItemId, function (err) {
if (!err) {
console.log("Successfully deleted");
res.redirect("/admin");
} else {
console.log(err);
}
});
});
I get this error when I press the delete button:
reason: Error: Argument passed in must be a single String of 12 bytes or a string of 24 hex
characters

Okay, this is how I solved I am not sure if it's the correct way, but it works.
Form admin.ejs
<% events.forEach( function (event) { %>
<form class="form-events" action="/delete" method="post">
<div class="card col-lg-3" style="width: 18rem;">
<img class="card-img-top">
<div class="card-body">
<h5 class="card-title"><%= event.title %></h5>
<p class="card-text"><%= event.description %></p>
<p class="card-text"><%= event.date %> </p>
<p class="card-text"><%= event.capacity %></p>
Update
<button name="deleteBtn" value="<%=event._id%>" type="submit" class="btn btn-danger">Delete</button>
</div>
</div>
<% }); %>
</form>
The app.js for the route
app.post("/delete", function (req, res) {
const deletedItemId = req.body.deleteBtn;
Event.findByIdAndDelete(deletedItemId, function (err) {
if (!err) {
console.log("Successfully deleted");
res.redirect("/admin");
} else {
console.log(err);
}
});
});
Now it works perfectly and for the database, but most stuff I googled where showing to use
/*for the route */
app.delete(“delete/:id”), function()
/*for the form */
<form method="POST" action="/delete/<%= event._id%>?_method=DELETE">
<button type="submit">Delete</button>
</form>
which I tried but got ran into some errors again and return to the original one which works, I don't really understand the whole app.post, app.delete because you also use the action /delete and then you can just remove it using mongoose, also I am not sure but for the form method in HTML it's said you only can use post and put, which confused me even more....

Related

Modal ajax.form validation ASP.NET MVC, error message not showing, modal not closing after succesful submit

i'm new to the ASP.net and i get easilly confused when jquery and Ajax get in the middle of a code.
I have a popup bootstrap Modal that show when i click on a button, the Modal contains an Ajax.form that allows me to create projects, i'm using HTML.validation to check if my form is filled correctly. I have two main problems :
When I enter valid informations in my form and i submit the form, the project is created succesfully but the Modal doesn't close automaticlly.
When i enter non-valid informations when i submit no message error apear, nonetheless when I close the modal and open it again, the errors apear.
I need your help to :
Close the modal once the submit form is valid.
Have the error message show in my modal form.
*This is a part of my main view :
enter code here
<!--validation script -->
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
<!-- Button trigger modal -->
<div>
<div>
<a class="btn btn-red ms-auto my-auto h-50"
href="#Url.Action("createProject", "ProjectSelection")" title="Nouveau projet"
data-bs-toggle="modal" data-bs-target="#Modal_NewProject"
ajax-target-id="Body_NewProject" data-bs-loader="Loader_NewProject">
<i class="feather-16" data-feather="plus"></i>
Créer projet
</a>
</div>
</div>
<br />
<!-- Modal View -->
<div class="modal fade" id="Modal_NewProject" tabindex="-1"
aria-labelledby="Label_NewProject" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="Label_NewProject">
Créer un Projet</h5>
<button type="button" class="btn-close"
data-bs-dismiss="modal" aria-label="Close"></button>
</div>
#using (Ajax.BeginForm("createProjectPost",
"ProjectSelection", new AjaxOptions { HttpMethod = "POST",
UpdateTargetId = "Body_NewProject" }, new { id = "projectForm" }))
{
<div id="Body_NewProject">
<div class="spinner-border" role="status"
id="Loader_NewProject">
<span class="visually-hidden">Loading...</span>
</div>
<!-- partial view "createProject" -->
</div>
}
</div>
</div>
</div>
<!---->
*And this is my partial view that containts the elements of the form
<div class="modal-body" id="frmProject">
<div class="input-group mb-3" id="">
#Html.DropDownListFor(m => m.Project.Domain,
new SelectList(Model.Domains, "IdDomain", "Name"),"Selectionner un domaine",
new { #class = "w-100", #id = "DomainSelection" })
#Html.ValidationMessageFor(m => m.Project.Domain, null,
new { style = "color: red;" })
</div>
<div class="input-group mb-3 mb-3 " id="teamSelection">
#Html.DropDownListFor(m => m.Project.Teams,
new SelectList(Model.Teams.Select(teamElement => teamElement.Name).ToList()),
"Selectionner une équipe", new { #class = "w-100" })
#Html.ValidationMessageFor(m => m.Project.Teams, null,
new { style = "color: red;" })
</div>
<div class="form-floating mb-3">
<input class="form-control " data-val-required="Le champ Projet est requis."
id="Project.Name" name="Project.Name" type="text" value="">
<label for="Project.Name" class="">Nom du projet</label>
#Html.ValidationMessageFor(m => m.Project.Name, null,
new { style = "color: red;" })
</div>
</div>
<div class="modal-footer mb-0">
<div class="panel-footer">
<button class="btn btn-secondary" data-bs-dismiss="modal"
type="button">Annuler</button>
<button type="submit" form="projectForm"
class="btn btn-red">Valider</button>
<div class="col-xs-10" id="lblstatus"></div>
</div>
</div>
*This is my Controller code
public ActionResult createProject()
{
//initialization code
return PartialView();
}
[HttpPost]
[ValidateAntiForgeryToken]
[HandleError]
public ActionResult createProjectPost(Project project)
{
#region Variable verification
if (!ModelState.IsValid)
{
Session["Error"] = true;
if (project.Domain == null)
{
Session["DomainError"] = true;
}
if (project.Teams == null)
{
Session["TeamError"] = true;
}
if (project.Name == null)
{
Session["NameError"] = true;
}
ViewData["project"] = "create";
//return View("ProjectSelectionPage");
return PartialView(project);
}
#endregion
#region Initialisation
//initilization code
#endregion
#region Check possible copy of the project
if (projectDB.Exist(project.Name))
{
//Check that this project doesn't exist in the database
//Create a session variable that will trigger an error message
Session["Error"] = true;
Session["NameCopy"] = true;
ViewData["project"] = "create";
return PartialView(project);
}
#endregion
#region Project to database and generate name
//Add the project to the database
#endregion
return PartialView();
}
It's been several days since i'm searching for an answer, i either missed one or didn't use it correctly.
enter image description here
Thank you

Deleting from Database Using Jquery Ajax Request in Nodejs

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');
//...

How to display data from multiple tables in vue js and Laravel?

I'm trying to display data from three tables in my database on one page. I've managed to do it, everything is working the way I want but I have an error: Error in render: "TypeError: Cannot read property 'file' of undefined"
It seems like I'm getting this error when trying to retrieve the videos data WITHOUT using a v-for loop.
Is it possible to display data on a page without using a v-for loop?
Here is my code.
CandidateProfileController.php:
public function index()
{
$videos = Video::all();
$resumes = Resume::all();
$profile = CandidateProfile::all();
return Response::json(array(
'videos' => $videos,
'resumes' => $resumes,
'profiles' => $profile
));
}
CandidateProfileIndex.vue:
<template>
<div class="col-md-12 grid-margin stretch-card">
<div class="card">
<div class="card-body">
<h3 class="card-title">My Profile</h3>
<b-container class="bv-example-row">
<b-row>
<b-embed
type="video"
aspect="16by9"
:src="`${$store.state.serverPath}/storage/videos/${videos[0].file}`"
allowfullscreen
controls
></b-embed>
</b-row> <br>
<b-row>
<b-col class="text-right" cols="8"></b-col>
<b-col class="text-right" cols="2">
<b-embed
type="video"
aspect="16by9"
:src="`${$store.state.serverPath}/storage/videos/${videos[1].file}`"
controls
class="video-thumbnail"
></b-embed>
</b-col>
<b-col class="text-right" cols="2">
<b-embed
type="video"
aspect="16by9"
:src="`${$store.state.serverPath}/storage/videos/${videos[2].file}`"
controls
class="video-thumbnail"
></b-embed>
</b-col>
</b-row>
</b-container>
<br>
<b-container v-for="(profile, index) in profiles" :key="index">
<div class="b-row">
<div class="b-col" v-for="(resume, index) in resumes" :key="index">
<h4 style="float: left;">Resume:</h4>
<span style="font-size: 0.88rem;">{{resume.file}}</span><br><br>
</div>
</div>
<div class="b-row">
<div class="b-col">
<h4>Experience</h4>
<p>{{profile.experience}}</p>
</div>
</div>
<div class="b-row">
<div class="b-col">
<h4>Additional Skills</h4>
<p>{{profile.skills}}</p>
</div>
</div>
</b-container>
</div>
</div>
</div>
</template>
<script>
import * as groupedService from '../../services/grouped_data_service.js';
export default {
name: "candidateProfileIndex",
data() {
return {
profiles: [],
videos: [],
resumes: [],
};
},
mounted() {
this.loadGroupedData();
},
methods: {
loadGroupedData: async function() {
try {
const response = await groupedService.loadGroupedData();
console.log(response);
this.resumes = response.data.resumes;
this.videos = response.data.videos;
this.profiles = response.data.profiles;
console.log(this.resumes);
} catch (error) {
this.$toast.error("Some error occurred, please refresh!");
}
}
}
}
</script>
grouped_data_service.js:
import {http, httpFile} from './http_service';
export function loadGroupedData() {
return http().get('/candidate-profile');
}

Delete item in the database using a simple button on angular 7

im trying to create a delete button on one side of a word that i get from the data base and i cant figure out how to do it
I already delete the word but i have to use a input form on the html and i have to write by hand the word i that i want to delete, but this is no god for user experience, so thats why im seeking that X button
this is my html
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-body">
<h4 class="card-title">Hashtags</h4>
<h6 class="card-subtitle">Hashtags <code> uno</code> agregar.</h6>
<div class="row button-group">
<div class="col-lg-2 col-md-4" *ngFor="let hash of getHashtag">
<form [formGroup]="form" (ngSubmit)="onDelet(form.value)">
<button class="ti-close" type="submit"></button >
<input type="text" formControlName="hashtag" > {{hash}} <br>
<p id="competitors" > {{hash}}</p>
</form>
</div>
</div>
</div>
</div>
<div class="card">
this is my componet file:
public onDelet(){
this._getHashtag.deleteHashtag(this.form.value.hashtag).subscribe(
result =>{
// console.log(result)
this._getHashtag.getHashtag().subscribe(
resultado =>{
this.getHashtag = resultado
this.getHashtag = this.getHashtag.result
// console.log("Resultado", this.getHashtag)
},
error => {
var mensajeError = <any>error;
}
);
}
)
}
this is my service component:
deleteHashtag(hastagdel:string){
let header = new Headers({"Content-Type":"application/json"})
return this._http.post(this.url + "/removeHashtags" ,{hashtags:[hastagdel]}, {withCredentials:true})
}
I'm pretty sure you want to use http.delete, not http.post in your service.
http.post adds something to the db,
http.delete removes something,
http.put modifies something, and
http.get retrieves something from the db.
There are other http options, but those are the main ones.

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.