How can I make my Delete Entry Button Functional - html

Pardon my novice as I am new to coding. I have been trying to get my delete button to work both on my webpage and mysql, but my delete button just takes me to a url /delete page. I do not get any errors, but my confirm delete button does not remove the entry, but takes me to another blank page. If any advice could be spared it would be greatly appreciated. Here is some code, if more is need let me know. Thanks again.
<template>
<div class="between:flex bottom:margin-3">
<div class="center: flex-items">
<span class="right:margin-1">Show</span>
<select v-model="currentEntries" class="select" #change="paginateEntry">
<option v-for="se in showEntries" :key="se" :value="se">
{{ se }}
</option>
</select>
<span class="left:margin-1">Entries</span>
<div class="end:flex"></div>
</div>
</div>
<div id="tableHolderDiv">
<table class="table table-striped">
<thead>
<tr>
<th scope="col">ID</th>
<th scope="col">Location</th>
<th scope="col">End User</th>
<th scope="col">Order Number</th>
<th scope="col">Date</th>
<th scope="col">Application</th>
<th scope="col">Service Tech</th>
<th scope="col">Department</th>
<th scope="col">Hours</th>
<th scope="col">Travel Hours</th>
<th scope="col">Contact Name</th>
<th scope="col">Reason</th>
</tr>
</thead>
<tbody>
<tr
v-for="row in serviceEntries"
:key="row.id"
#click="alertID(row.id)"
>
<th scope="row">{{ row.id }}</th>
<td>{{ row.location }}</td>
<td>{{ row.end_user }}</td>
<td>{{ row.order_number }}</td>
<td>{{ row.date }}</td>
<td>{{ row.application }}</td>
<td>{{ row.service_tech }}</td>
<td>{{ row.department }}</td>
<td>{{ row.hours }}</td>
<td>{{ row.travel_hours }}</td>
<td>{{ row.contact_name }}</td>
<td>{{ row.reason }}</td>
<a
href="/delete/{{this.id}}"
type="button"
class="btn btn-light btn-small"
onclick="event.stopPropagation(); return confirm('Are you sure you want to delete this entry?');"
><i class="bi bi-trash"></i> Delete</a
>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import axios from "axios";
export default {
name: "ServiceTable",
computed: {
serviceEntries() {
return this.$store.state.serviceEntries;
},
},
methods: {
alertID(id) {
this.$router.push({
path: `/modify/${id}`,
});
},
},
async onDelete() {
if (!confirm("Are you sure you want to delete this entry?")) {
return;
}
await axios.delete(`/api/service/delete/${this.id}`);
},
alertID(id) {
this.$router.push({
path: `/modify/${id}`,
});
},
};
</script>
This is in my index.js
async deleteServiceEntry() {
return new Promise((resolve, reject) => {
axios({
method: "delete",
url:
prefix +
"/api/service/delete/",
headers: { "Content-Type": "application/json" }
})
.then(function(response) {
//handle success
console.log(response);
resolve(true);
})
.catch(function(response) {
//handle error
console.log(response);
reject(false);
});
});
},
This is in my app.js
app.delete("/api/service/:id", (req, res) => {
// console.log("DELETE /api/user/" + req.params.id + " called");
pool.query(
"DELETE FROM `master` WHERE id = ?",
[req.params.id],
function (error, results, fields) {
if (error) res.json(error);
else res.json(results);
}
);
});
app.delete("/api/service/:id", (req, res) => {
pool.query(
"DELETE FROM `master` WHERE id= ? AND location = ? AND end_user = ? AND order_number = ? AND date = ? AND application = ? AND service_tech = ? AND department = ? AND hours = ? And travel_hours = ? AND contact_name = ? AND reason = ?",
[req.params.id, req.params.location, req.params.end_user, req.params.order_number, req.params.date, req.params.application, req.params.service_tech, req.params.department, req.params.hours, req.params.travel_hours, req.params.contact_name, req.params.reason],
function (error, results, fields) {
if (error) res.json(error);
else res.json(results);
}
);
});

It is redirecting to a new page because of the href link in the anchor tag. You should call the method deleteServiceEntry on the click and it should work fine. What you can do is:
<a
href="#"
type="button"
class="btn btn-light btn-small"
#click="deleteServiceEntry($event,row.id)"
><i class="bi bi-trash"></i> Delete</a
>
Then in the method:
async deleteServiceEntry(event,id) {
event.preventDefault();
const verify = confirm("Are you sure you want to delete this entry?");
if (verify) {
return new Promise((resolve, reject) => {
axios({
method: "delete",
url:
prefix +
"/api/service/delete/"+id,
headers: { "Content-Type": "application/json" }
})
.then(function(response) {
//handle success
console.log(response);
resolve(true);
})
.catch(function(response) {
//handle error
console.log(response);
reject(false);
});
});
},
}
Hope this was helpful.

Related

Why I cannot see json data in table?

I am trying to display json data in tree hierachy table with vue.js. Unfortunally I cannot see any data inside of the table. The path is correct, I have checked this by URL adress, the format as well. My goal is to create tree hierarchy table, with action button for removing layers. I would like to mention thath I am new in Vue.js framework, so this is not maybe the best option how to work with fetched data from json file.
HTML:
<table>
<thead>
<tr>
<th>Name</th>
<th>Parent</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="item in items" :key="item.id">
<td>{{ item.name }}</td>
<td>{{ item.parent }}</td>
<td>
<button #click="toggleChildren(item)">Toggle Children</button>
</td>
<template v-if="item.childrenVisible">
<tr v-for="child in item.children" :key="child.id">
<td>{{ child.name }}</td>
<td>{{ child.parent }}</td>
<td>
<button #click="toggleChildren(child)">Toggle Children</button>
</td>
</tr>
</template>
</tr>
</tbody>
</table>
</div>
Vue.js code
<script>
fetch('data/vue-data.json')
.then(response => response.json())
.then(data => {
new Vue({
el: '#app',
data: {
items: data.items
},
methods: {
toggleChildren(item) {
item.childrenVisible = !item.childrenVisible;
},
}
});
})
</script>
you create your app in advance. also where is your #app container?
<div id="app">
<!-- your table data -->
</div>
and for the js
new Vue({
el: '#app',
// data should return an object, not be an object
data() {
return {
items: [] // default value, could also be null
}
},
// called on initialization, read about lifecycle hooks
mounted() {
fetch('data/vue-data.json').then(response => { this.items = response.json() })
},
methods: {
toggleChildren(item) {
item.childrenVisible = !item.childrenVisible;
},
}
});

Looping over JSON array using *ngFor

I currently have the following JSON file:
[
{
"Arsenal": {
"form": {
"away": 4.6064800860172,
"home": 2.2108841763771
},
"stadium": "Stadium 1"
}
},
{
"Man City": {
"form": {
"away": 4.9473459270023,
"home": 5
},
"stadium": "Stadium 2"
}
},
{
"Man Utd": {
"form": {
"away": 5,
"home": 3.2296790061981
},
"stadium": "Stadium 3"
}
}
]
and I want to display this data in a table. I currently have a service that retrieves the JSON file and returns it
public getJSON(): Observable<any> {
return this.http.get('assets/teams.json')
.map(
(response: Response) => {
const data = response.json();
return data;
}
);
}
I then subscribe to it in my component and save it to teams.
teams = [];
loadJSON() {
this.teamService.getJSON().subscribe(
(teams: any[]) => this.teams = teams,
(error) => console.log(error)
);
}
and using the following HTML
<div class="container">
<table class="table">
<thead>
<tr>
<th>Team</th>
<th>Home</th>
<th>Away</th>
<th>Stadium</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let team of teams | keys">
<td>{{ (team.value | keys)[0].key }}</td>
<td>{{ (team.value | keys)[0].value["form"]["home"] }}</td>
<td>{{ (team.value | keys)[0].value["form"]["away"] }}</td>
<td>{{ (team.value | keys)[0].value["stadium"] }}</td>
</tr>
</tbody>
</table>
</div>
gives the table seen below
Surely there must be a better way of doing this? How can I do this in a more straight-forward way, that is a lot more readable? For example, if the key was actually "Arsenal", "Man City" and "Man Utd" instead of 0, 1 and 2 respectively, it would be much more readable. Why does it have those keys instead? I'm used to coding in Python so it doesn't really make much sense to me.
A working stackblitz can be found here.
I propose to have your own Team object and map your JSON on it.
So in your teams.service you have:
public getJSON(): Observable<Team[]> {
return this.http.get('assets/teams.json')
.map(teams => teams.map(team => this.mapTeam(team)))
}
private mapTeam(res: any): Team {
const teamName = Object.keys(res)[0]
return new Team(
teamName,
{away: res[teamName].form.away, home: res[teamName].form.home},
res[teamName].stadium
)
}
Your Team class can be like this:
export class Team {
constructor(public name: string,
public form: { away: number, home: number },
public stadium: string) {
}
}
It's not the subject of your question but in this the Team class it's preferable to have private properties and have getter to access it.
In your component.ts:
Just call your service and assign the value of the subscribe: this.teamService.getJSON().subscribe(value => this.teams = value)
There are antother way to do this part but it's not your question too
And finally your html it's more readable:
<div class="container">
<table class="table">
<thead>
<tr>
<th>Team</th>
<th>Home</th>
<th>Away</th>
<th>Stadium</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let team of teams">
<td>{{ team.name }} </td>
<td>{{ team.form.home }}</td>
<td>{{ team.form.away }}</td>
<td>{{ team.stadium }}</td>
</tr>
</tbody>
</table>
</div>
The stackblitz here: https://stackblitz.com/edit/angular-gwj6nb

V-for not displaying records after his has fetched on console [duplicate]

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
I have init the array ArtificialInsemination[] on response received but its not showing or loading the records in the table. When I click the button its calls the functions viewRecords and sends the HTTP request successfully, but not loading into the table.
<div id="ArtificialInsemination" class="container">
<button v-on:click="viewRecords">View Record</button>
<table class="table table-striped">
<thead>
<tr>
<th>Cow Id</th>
<th>Bull Name</th>
<th>Semen Origin</th>
<th>Insemination Time</th>
<th>Pd Delivery Date</th>
</tr>
</thead>
<tbody>
<tr v-for ="artificialInseminationRecord in artificialInseminationRecords">
<td>{{ artificialInseminationRecord.cowId }}</td>
<td>{{ artificialInseminationRecord.bullUsedName }}</td>
<td>{{ artificialInseminationRecord.semenOrigin }}</td>
<td>{{ artificialInseminationRecord.inseminationTime }}</td>
<td>{{ artificialInseminationRecord.pdStatusDate }}</td>
</tr>
</tbody>
</table>
</div>
This is the vue
<script src="https://unpkg.com/vue#2.0.3/dist/vue.js"></script>
<script src="https://unpkg.com/axios#0.12.0/dist/axios.min.js"></script>
<script src="https://unpkg.com/lodash#4.13.1/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.debug.js"></script>
<script>
//class initialization
var ArtificialInsemination = new Vue({
el:'#ArtificialInsemination',
data: {
url:'http://localhost/dairyfarm/index.php',
artificialInseminationRecords: []
},
//invoke methods
methods: {
viewRecords:function () {
var data = new FormData()
data.append('function','viewRecords')
axios.post(this.url,data)
.then( function (response ) {
this.artificialInseminationRecords = response.data.data
}).catch(function (error) {
})
},
created: function(){
this.viewRecords()
}
}
})
</script>
You have a scoping issue, this inside a callback refers to the execution context of the callback not the Vue instance. You need to either assign this to something outside the callback:
// assign this to self
var self = this;
axios.post(this.url,data)
.then( function (response ) {
self.artificialInseminationRecords = response.data.data
}).catch(function (error) {
})
Or use an arrow function which do not create their own execution context:
axios.post(this.url,data)
.then( response => {
this.artificialInseminationRecords = response.data.data
}).catch(function (error) {
})
You decided to use created event, but you defined it as a method. :)
Look at this sample:
Async Data Mutation inside of Created Event
We only needed to add bind like this
viewRecords:function () {
var data = new FormData()
data.append('function','viewRecords')
axios.post(this.url,data)
.then( function (response ) {
this.artificialInseminationRecords = response.data.data
}.bind(this)).catch(function (error) {
})
}

How to fetch data from console output to table using angular2

I have a table in HTML, i need to fetch data from consoled output to the table. Please help.
HTML Code:
<table class="table">
<tr>
<th>Completed On</th>
<th>ID</th>
<th>ParticipantId</th>
</tr>
<tr *ngFor="let data of result">
<td>{{ data.completedOn }}</td>
<td>{{ data.id }}</td>
<td>{{ data.participantId }}</td>
</tr>
</table>
TS Code:
public result:any = [];
this.service
.getParticipent(comparedCampaign.id,token)
.subscribe(
participent => {
this.loading = false;
// this.result = data;
console.log( this.result);
var survey = this.surveyResults;
if(participent.length > 0) {
var data =[];
participent.map(function(item) {
var list = survey.filter(function(result) {
if(result.participantId) {
return result.participantId == item.id
}
})
data.push(list);
this.result = data;
console.log( this.result);
})
console.log(data);
} else {
alert('No Participent found!');
}
}, error => {
console.log(error)
})
}
}
From this i need to fetch CompletedOn, id and participantId to the table
JSON Consoled output:
[[{"satisfaction":"[object Object]","completedOn":"2017-08-22T08:52:55.788Z","id":3,"participantId":217},{"satisfaction":{"price":"less","recomondation":"1","winback":"reason6"},"completedOn":"2017-08-22T09:12:40.800Z","id":4,"participantId":217},{"satisfaction":{"price":"less","recomondation":"1","winback":"reason6"},"completedOn":"2017-08-22T11:36:04.861Z","id":5,"participantId":217},{"satisfaction":{"price":"less","recomondation":"1","winback":"reason6"},"completedOn":"2017-08-22T11:59:24.334Z","id":6,"participantId":217},{"satisfaction":{"price":"medium","customer":"yes","recomondation":"2","sales":["phone","Shop","webshop"],"webVist":"5","shopVist":"5","phoneVist":"5","prodandService":["{product_list}"],"importance":["Service"],"frequence":"quarter","satisfaction":"3"},"completedOn":"2017-08-22T12:20:54.280Z","id":7,"participantId":217},{"satisfaction":{"price":"medium","customer":"no","recomondation":"1","winback":"reason1","winback_quality":"reason2"},"completedOn":"2017-08-22T12:22:43.153Z","id":8,"participantId":217},{"satisfaction":{"prodandService":[{"index":"Orbiz"},{"index":"qwerq"},{"index":"asfd"},{"index":"test"},{"index":"test123"},{"index":"TestWD"},{"index":"IOS app"},{"index":"Lipstick"},{"index":"Foundation"},{"index":"lipstick"},{"index":"Website"},{"index":"App IOS"},{"index":"Shampoo Vanilla"},{"index":"Shampoo Strawberry"},{"index":"car"},"Lipstick"],"price":"medium","customer":"yes","recomondation":"4","sales":["phone"],"phoneVist":"3","importance":["Quality"],"frequence":"quarter","satisfaction":"3"},"completedOn":"2017-08-28T09:39:54.676Z","id":10,"participantId":217},{"satisfaction":{"prodandService":[{"index":"Orbiz"},{"index":"qwerq"},{"index":"asfd"},{"index":"test"},{"index":"test123"},{"index":"TestWD"},{"index":"IOS app"},{"index":"Lipstick"},{"index":"Foundation"},{"index":"lipstick"},{"index":"Website"},{"index":"App IOS"},{"index":"Shampoo Vanilla"},{"index":"Shampoo Strawberry"},{"index":"car"},"Foundation","IOS app","test123","test"],"price":"medium","customer":"yes","recomondation":"5","sales":["visits"],"salesVist":"3","importance":["Quality"],"frequence":"year","satisfaction":"5","knowledge":["IOS app","Foundation","Website"],"development":"littleLess","suppliers":"yes","competators":"60","competators_reasons":"Quality","Need":["{product_list}"],"service":"5","collaboration":"4","continuedCollaboration":"3","improvements":["Service","Price"],"winback":"reason3"},"completedOn":"2017-08-28T14:45:13.991Z","id":11,"participantId":217},{"satisfaction":{"prodandService":[{"index":"Orbiz"},{"index":"qwerq"},{"index":"asfd"},{"index":"test"},{"index":"test123"},{"index":"TestWD"},{"index":"IOS app"},{"index":"Lipstick"},{"index":"Foundation"},{"index":"lipstick"},{"index":"Website"},{"index":"App IOS"},{"index":"Shampoo Vanilla"},{"index":"Shampoo Strawberry"},{"index":"car"},"TestWD","Lipstick"],"price":"less","recomondation":"4","sales":["phone"],"phoneVist":"3","importance":["Quality","Assortment"],"frequence":"quarter","satisfaction":"4","knowledge":["IOS app"],"Need":["TestWD","Lipstick"],"development":"same","suppliers":"yes","competators":"60","competators_reasons":"Assortment","service":"4","collaboration":"4","continuedCollaboration":"3","improvements":["Assortment"],"winback":"reason4"},"completedOn":"2017-09-01T14:23:04.533Z","id":13,"participantId":217}]]
with error:
"EXCEPTION: Cannot set property 'result' of undefined"
Please Help.
Thanks in advance
You need to access the 0th index of the array and then assign to the result,
this.service.getParticipent(comparedCampaign.id,token).subscribe(
participent => {
this.result = participent[0];
}
then you can iterate over and display as you mentioned above,
<tr *ngFor="let data of result">
<td>{{ data.completedOn }}</td>
<td>{{ data.id }}</td>
<td>{{ data.participantId }}</td>
</tr>
i guess you are showing array in wrong format so try this
this.service.getParticipent(comparedCampaign.id,token).subscribe(
participent => {
this.result = participent;
}
and use your array like this
<tr *ngFor="let data of result">
<td>{{ data?.completedOn }}</td>
<td>{{ data?.id }}</td>
<td>{{ data?.participantId }}</td>
</tr>
also please try to print whole array in HTML too, for better understanding like this
{{result | json}}

using ng-repeat to display data in json file

I am new to angularjs. I want to display the data in the following json file using ng-repeat.
http://www.cricbuzz.com/api/match/current
But I'm confused as there is a number in the data as key to each object. Can someone help me?
THis is a basic way to do it
Partial
<div ng-controller="Ctrl" >
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in rows">
<td>#{{ row.id}}</td>
<td>{{ row.series.name | uppercase }}</td>
</tr>
</tbody>
</table>
</div>
Controller
angular.module('app').controller('Ctrl', ['$scope', 'Resource', function ($scope, Resource) {
var pageChanged = function () {
$scope.myPromise = Resource.get({}, function (response) {
$scope.rows = response;
});
};
pageChanged();
}])
.factory('Resource', ['$resource', function($resource) {
return $resource('http://www.cricbuzz.com/api/match/current', {
}, {
'get': {
method: 'GET',
headers: {"Content-Type": "application/json"}
}
});
}]);