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

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.

Related

SQL Query won't run after pressing button

I am trying to run the searchSQL query with the input from the searchbar after pressing the button. The 'sql' query runs on start.
When pressing the button it won't update the images according to the input from the search?
#using WebMatrix.Data
#{
var db = Database.Open("MTGDecks");
var sql = "SELECT * FROM Cards WHERE isPopular <> 0";
var searchSQL = "SELECT * FROM Cards WHERE cardName LIKE CONCAT ('%', #0, '%')";
var searchValue = Request.Form["searchBox"];
if (IsPost)
{
var searching = db.Query(searchSQL, searchValue);
}
var output = db.Query(sql);
}
<link href="~/Content/Site.css" rel="stylesheet" />
<h2>All Cards</h2>
<form method="post" action="/Home/Index">
<input type="text" name="searchBox" />
<button type="submit" class="btn">Search</button>
Make New Deck
<div class="row">
<div class="row justify-content-center">
#foreach (var row in output)
{
<div class="col-4">
<div class="card">
<img src="#row.imageURL" class="card-img-top" alt="...">
<div class="card-body">
<h5 class="card-title">#row.cardName</h5>
<p class="card-text">#row.oracleText</p>
Details
</div>
</div>
</div>
}
</div>
</div>
</form>
I'm unsure of what to do.
ok, going out on a limb here... your "button" is the href that redirects you to the details of the #row.cardID
In your code block you have it set up to do some stuff, but you never actually call it... If I were doing this in Blazor (razor syntax) the solution would be something like
#page "/myPage/{int: cardID}
HTML HERE
//Pseudocode, don't copy/paste
#code
{
public override void OnParametersSet ()
{
if (cardID != null)
Run The COde!!
}
}
So, basically, you're missing wiring up some kind of page event. There's a TON wrong with everything you're doing, but... hopefully this will get you to the next logical question.

Angular - can i limit the no of dynamically created cards on the page?

<div class="row">
<div class=" col-xl-8 offset-xl-2">
<div class=" row">
<div *ngFor="let pokemon of pokemons | searchFilter: filterName:'name'; let i = index " class=" col-md-6">
<div style="border-radius: 15px 50px;" class="card mb-3 bg-{{getType(pokemon)}}"
[routerLink]="['/view', pokemon.name]">
<div class="card-body">
<div class="row">
<div class="col-7 col-sm-8">
<h3 class="card-title">{{pokemon.name | titlecase}}</h3>
<span *ngFor="let type of pokemon.types "
class="badge border rounded-pill me-1 bg-{{getType(pokemon)}}">
{{type.type.name | titlecase}}
</span>
</div>
<div class="col-5 col-sm-4">
<img src="https://pokeres.bastionbot.org/images/pokemon/{{pokemon.id}}.png"
class="img-fluid" alt="...">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm text-center">
<button class="btn draw-border" (click)="loadMore()">
<div class="spinner-border spinner-border-sm" role="status" *ngIf="loading"></div>
{{loading ? 'Loading...' : 'Load More'}}
</button>
</div>
</div>
</div>
This is my code nothing special just a simple ngfor , currently the ngfor dynamically creates about 30 cards (don't know exactly) before the button to load more appears , I'm using infinite scrolling btw , so can I limit the number of cards created to about say 10-15 before ,and then the button to load more appears , is this doable?
I’m making the assumption that the load more button will fetch more results from the api if it is currently showing all results.
If you are initially loading 30 but only want to show 10 initially and 10 more each button press o would give two possible solutions.
Update API
If you have access to the Api and can pass in Params for pagination results. I would go that route first, since it is the cleanest. If not maybe the second option instead.
Or
Update the component to manage your results array. It can be done as so in the TypeScript file.
pokemons: Pokemon[] =[]
pokemonBuffer: Pokemon[] = [] // holds the Pokemon you have but not yet showing
countToLoad = 10;
ngOnInit() {
this.loadMore();
}
loadMore() {
if(this.pokemonBuffer.length < this.countToLoad) {
this.http.get(.....)
.subscribe(results => {
this.pokemonBuffer.concat(results);
this.pokemon.push(this.pokemonBuffer.splice(0, this.countToLoad)
})
} else { // the buffer has enough, take it from there
this.pokemon.push(this.pokemonBuffer.splice(0, this.countToLoad)
}
}
If you would like to change this just add a 'limit' query parameter to the GET request, e.g. ?=60. You can use 'offset' to move to the next page, e.g. ?limit=60&offset=60.
edit :
for this api this works
from the documentation ^^^

Deleting from list in vue.js

I am having some problem with my code. Iam trying to delete a "joke" from a list but it always takes out the joke that i typed in before the joke i am deleting. I don't quite get what i am doing wrong here.
delJoke(index) {
this.setList.splice(index,1);
this.viewJoke = {};
console.log(this.setList.splice);
},
<div class="col list-group-item" v-for="(view, index) in viewJoke" :key="index">
<div class="col">Joke: {{view.joke}} </div>
<div class="col"> Punchline: {{view.punchline}}</div>
<div class="col">Category: {{view.category}}</div>
</div>
<button type="button" class="btn btn-dark" active href="#" v-for="joke in viewJoke"
#click="delJoke(index)"></button>
try to pass joke object into function, and find index
delJoke(joke) {
var index = this.setList.indexOf(joke)
... your code
}
your delete button must be inside the v-for.
and the delete function should look like this
delJoke(index) {
this.viewJoke = this.viewJoke.splice(index,1);
}

TypeScript Angular: Can you have an (click) event with an object property as its value?

I am trying to create a dynamic error card, with different error messages and with a retry button.
Here is a snippet of my typescript object:
errorCard: any = [];
if(error){
this.errorCard.errorMessage = "oops try again"
this.errorCard.buttonFunc = "retry()";
}
Now this is my view:
<div class="card-block">
<div class="card-media-block wrap">
<div class="card-body">
<span class="card-media-title">
{{errorCard.errorMessage}} // works as expected
</span>
...
<div class="card-footer">
//this click is where I would like it to call the function that is tied to that property in this case retry()
<button (click)="errorCard.buttonFunc"><i class="fas fa-redo-alt"></i> Retry</button>
</div>
I do not receive any errors in the console with this, and the function does not get triggered.
I thank you guys in advance for your help!
Assuming that your Component is something like this:
import { Component } from '#angular/core';
#Component({...})
export class YourComponent {
errorCard = {};
...
retry() {
console.log('Retry Got Called');
}
}
Why don't you simply call the retry method like this(<button (click)="retry()">Retry</button>):
<div class="card-block">
<div class="card-media-block wrap">
<div class="card-body">
<span class="card-media-title">
{{errorCard.errorMessage}} // works as expected
</span>
...
<div class="card-footer">
//this click is where I would like it to call the function that is tied to that property in this case retry()
<button (click)="retry()"><i class="fas fa-redo-alt"></i> Retry</button>
</div>
</div>
</div>
</div>
Give this Working Sample StackBlitz a try.

Angular + Typescript: Add to array, ng-repeat adds blank row

Trying to add a new object to an array and have it show up in an ng-repeat div. I add the object, look at the array in Chrome's dev tools and can see the new object in there, but the ng-repeat section just has a blank row. I've search throughout StackOverflow, implemented many solutions and still have this problem.
HTML:
<div ng-repeat="subItem in ec.mainItem.SubItems">
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-3 h4">
<button class="btn-link">{{subItem.Name}}</button>
</div>
<div class="col-md-6">
{{subItem.Description}}
</div>
</div>
</div>
</div>
</div>
ItemCtrl.ts
module MainItemApp {
'use strict'
export class MainItemEntryCtrl implements IMainItemCtrl {
static $inject = ['$scope', '$routeParams', 'ItemSvc'];
public mainItem: MainItem; //this has an array on it named SubItems
public sub_item_name: string;
public sub_item_description: string;
public sub_item_date: Date;
public sub_item_start_date: Date;
public sub_item_end_date: Date;
public sub_item_descriptive_location: string;
public sub_item_short_location: string;
constructor($scope, $routeParams: IItemEntryRouteParams, itemSvc: ItemSvc) {
this.id= this.getId($routeParams.id);
if (this.id!= undefined) {
itemSvc.getMainItem(this.id).then(
(data) => this.mainItem = data);
}
}
addSubItem() {
var subItem = {
id: '',
name: this.sub_item_name,
itemDate: this.sub_item_date,
startDate: this.sub_item_start_date,
endDate: this.sub_item_end_date,
description: this.sub_item_description,
descriptiveLocation: this.sub_item_descriptive_location,
shortLocation: this.sub_item_short_location,
geoLat: '',
geoLong: '',
groupItems: []
};
this.mainItem.SubItems.push(subItem);
}
}
When I click a button, AddSubItem runs, the item gets created and after the push, I can hover over subItems and see the array has two objects, the one I loaded with and the one I pushed, but the HTML that's generated gives me this:
<div ng-repeat="subItem in ec.mainItem.SubItems">
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-3 h4">
<button class="btn-link">Some Item</button>
</div>
<div class="col-md-6">
Some Description
</div>
</div>
</div>
</div>
</div>
<div ng-repeat="subItem in ec.mainItem.SubItems">
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-3 h4">
<button class="btn-link"></button>
</div>
<div class="col-md-6">
</div>
</div>
</div>
</div>
</div>
Any ideas? Any help would be greatly appreciated!
Sorry, bad post, I figured it out (isn't it always like that, as soon as you make a fool of yourself and ask, you figure it out). My data was coming back from the API with capitalized property names (i.e. Name, Description) and I was adding an object where the names were lowercase (i.e. name, description) so of course there was nothing to show in the newly added row. So I synced up the names coming from my API with the names in the Typescript classes and everything is working now. So of course when I searched for the answer, I couldn't find it: no one posted "Hey dummy! Check the casing on your properties!"
So I think I will leave this up just in case someone else runs across the same problem and it sparks them to check their casing.