Fetched data duplicates itself after sorting - javascript

I fetched data by using fetch api into a table. I sort my data by clicking on column headers. It works but after it's sorted,it duplicates data. I checked on it,but i guess there's someting i've missed.
let data =[];
function veriAl()
{
fetch('https://jsonplaceholder.typicode.com/users')
.then(response =>{
if(!response.ok)
{
throw Error("ERROR");
}
return response.json();
})
.then(veri => {
data=veri;
veriEkle(data);
}).catch(error => {
console.log(error);
});
}
const sort_data = (field) =>
{
data.sort((a,b) => {
let valueA=a[field];
let valueB= b[field];
if(valueA<valueB)
{
return -1;
}
else if(valueB>valueA)
{
return 1;
}
return 0;
})
console.log("sıralandı"+field+"e göre",data);
veriEkle(data);
}
const veriEkle =(array)=>
{
const html=array.map(user =>{
return `<table class="user">
<td> ${user.id}</td>
<td>${user.name}</td>
<td>${user.username}</td>
<td>${user.email}</td>
<td>${user.address.street}/${user.address.suite}/${user.address.city}</td>
</table>
`;
}).join("");
console.log(html); document.querySelector('#veri_tablo').insertAdjacentHTML("afterbegin",html);
}
veriAl();
<div class="container">
<div class="row justify-content-center">
<table class="table" id="veri_tablo">
<thead class="thead-dark">
<tr>
<th onclick="sort_data('id')">ID</th>
<th onclick="sort_data('name')">Name</th>
<th onclick="sort_data('username')">Username</th>
<th onclick="sort_data('email')">Email</th>
<th onclick="sort_data('address')">Adres</th>
</tr>
</thead>
</table>
<div>
</div>

console.log("sıralandı"+field+"e göre",data);
veriEkle(data); //---->Here
You should maybe edit here like veriEkle(...data); or you should use filter function instead of "sort"

There seems to be nothing wrong with your data. It's not being duplicated. It is the html that's being duplicated. You're appending html without removing the existing entries. You should have a container element and change the inner html of that container instead.
Your js should look something like this...
//...
const veriEkle = (array) => {
const html = array.map(user => {
return `<tr class="user">
<td> ${user.id}</td>
<td>${user.name}</td>
<td>${user.username}</td>
<td>${user.email}</td><td>${user.address.street}/${user.address.suite}/${user.address.city}</td>
</tr>
`;
}).join("");
console.log(html);
document.getElementById('table_content').innerHTML = html;
}
And your html
<div class="container">
<div class="row justify-content-center">
<table class="table" id="veri_tablo">
<thead class="thead-dark">
<tr>
<th onclick="sort_data('id')">
ID
</th>
<th onclick="sort_data('name')">
Name
</th>
<th onclick="sort_data('username')">
Username
</th>
<th onclick="sort_data('email')">
Email
</th>
<th onclick="sort_data('address')">
Adress
</th>
</tr>
<tbody id="table_content" /> //the container element
</thead>
</table>
<div />
</div>
</div>
PS Using the innerHTML property is not considered best practice and you should look at this link for the best ways to create and render elements from html strings.

Related

Creating HTML from local storage data

I want to take data from my local storage and show it dynamically. In this table below is the code that I tried but it is not working.
<script>
var cart= JSON.parse( localStorage.getItem('Mylinklist'));
$.each(Mylinklist, function(key, value){
$('tbody').append(`<tr>
<td>${cart.name}</td>
<td>${cart.url}</td>
</tr>`)
})
</script>
<div id="actionerpanel" class="col col-lg-6 col-12 ">
<div class="rapi-card m-lg-5 m-1">
<b class="rapi-card-colored-header p-3 mb-2">Quick Links <span>+</span></b>
<div class="container">
<div class="row justify-content-center "><table class="table">
<thead>
<tr>
<th scope="col">Link Name</th>
<th scope="col">Url</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
You can use insertAdjacentHTML and literals templates for this kind of operation.
var carts = [{
id: 'id1',
name: 'test',
url: 'url'
}, {
id: 'id2',
name: 'test2',
url: 'url2'
}] //Fake localstorage replace it with JSON.parse
carts.forEach(cart => {
let button = `<button onclick="alert('Item id : ${cart.id}')">Click</button>`,
row = `<tr id="item_${cart.id}"><td>${cart.name}</td><td>${cart.url}</td><td>${button}</td></tr>`;
document.querySelector('tbody').insertAdjacentHTML('beforeend', row)
})
//OR
for (let cart of carts) {
let button = `<button onclick="alert('Item id : ${cart.id}')">Click</button>`,
row = `<tr id="item_${cart.id}"><td>${cart.name}</td><td>${cart.url}</td><td>${button}</td></tr>`;
document.querySelector('tbody').insertAdjacentHTML('beforeend', row)
}
<table class="table">
<thead>
<tr>
<th scope="col">Link Name</th>
<th scope="col">Url</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody></tbody>
</table>
You can make it with plain JS like this. I had to comment out the places with localstorage. Because access to localStorage is not allowed on SO. As soon as you add them, it works.
const arr = [
{id: 123, name: "google", url: "https://www.google.com"},
{id: 124, name: "bing", url: "https://www.bing.com"},
]
// store to localStorage
// localStorage.setItem('Mylinklist', JSON.stringify(arr));
// get from localStorage
// const data = JSON.parse(localStorage.getItem('Mylinklist'));
const table = document.querySelector('.table');
// change obj.forEach to data.forEach because in SO you cant use localStorage!!!
arr.forEach((e) => {
let tr = document.createElement('TR');
let td_name = document.createElement('TD');
let td_url = document.createElement('TD');
td_name.innerHTML = e.name
td_url.innerHTML = e.url
tr.append(td_name)
tr.append(td_url)
table.append(tr)
})
<div class="row justify-content-center "><table class="table">
<thead>
<tr>
<th scope="col">Link Name</th>
<th scope="col">Url</th>
<th scope="col">Actions</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>

Getting value inside a tag in react from event.target

I just encountered a problem if anyone could help me in this it would be great!!
here's a code i am working on
const loc = props.filtered.map((item,i)=>{
if(typeof props.filtered[i].scan != "undefined"){
return props.filtered[i].scan.map((items,idx)=>{
return <li>{props.filtered[i].scan[idx].location}</li>
})
}
})
In this code you can see that it returns a li tag with information inside.
Now the problem is that i am putting all this data inside a table a basic HTML one. Now as soon i have a onClick function on Tr and do event.target i get "the required data"
instead i want only the data instead of the data with li tags
also the typeOf is showing that it is a object
here is the onclick code
<table className="table ">
<thead>
<tr>
<th scope="col">AWBNO</th>
<th scope="col">TRANSPORTER</th>
<th scope="col">SOURCE</th>
<th scope="col">DESTINATION</th>
<th scope="col">Start</th>
<th scope="col">ETD</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
<tr>
<td onClick={click} id="test" className="try">{awb}</td>
<td>{Transporter}</td>
<td>{Source}</td>
<td>{Destination}</td>
<td>{start}</td>
<td>{etd}</td>
<td className="forstatus">{status}</td>
</tr>
</tbody>
</table>
EDIT:
onClick-function:
function click (event){
var y = document.getElementById("test").innerText;
console.log(y) console.log( event.target.value)
}

While hooping an array of objects in Svelte, how can I display the iteration count?

I am iterating a JSON with the help of Svelte's onMount method. I have displayed the data in a table.
<script>
import { onMount } from "svelte";
const apiURL = "https://gist.githubusercontent.com/Goles/3196253/raw/9ca4e7e62ea5ad935bb3580dc0a07d9df033b451/CountryCodes.json";
let countries = [];
onMount(async function() {
const response = await fetch(apiURL);
countries = await response.json();
});
</script>
<table class="table table-bordered">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Code</th>
</tr>
</thead>
<tbody>
{#if countries}
{#each countries as country }
<tr>
<td>{index + 1}</td>
<td>{country.name}</td>
<td>{country.code}</td>
</tr>
{/each}
{:else}
<p>There are no countries</p>
{/if}
</tbody>
</table>
What I have not been able to do is add an iteration count column. Using {index + 1}.
How do I get the desired result?
Index is a second argument of the each loop in svelte
{#each countries as country, index }
<tr>
<td>{index + 1}</td>
<td>{country.name}</td>
<td>{country.code}</td>
</tr>
{/each}
Here is the docs link

How to get the value of a specific row in a table in vuejs?

How can I get the value of a specific row in a table in VueJS 2?
This is my table right now
Below is my code to generate a table and two buttons that will show a modals; one is to edit detail and the other is to show the QR Code coming from the database. I want to get the last value of the loop and put it in SHOW QR Button and the Show QR Button will contain the last value from the loop.
<div class="myTable table-responsive">
<table class="table">
<thead class="thead-dark">
<tr>
<th>Member ID</th>
<th>First Name</th>
<th>Middle Name</th>
<th>Last Name</th>
<th>Address</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="result in filteredList" :key="result.id">
<td>{{result.Memb_ID}}</td>
<th>{{result.First_Name}}</th>
<th>{{result.Middle_Name}}</th>
<th>{{result.Last_Name}}</th>
<th>{{result.Address}}</th>
<div class="row justify-content-center">
<b-button v-b-modal.showDetails size="lg" class="showDetails" variant="danger">Edit</b-button>
<b-button v-b-modal.modalQR size="lg" class="showQR" variant="success">Show QR</b-button>
</div>
</tr>
</tbody>
</table>
</div>
This is my modal where I want to have different QR for every user to be inserted.
Below is my modal for the Show QR Button
<b-modal id="modalQR" title="Generated Details">
<div class="showQR text-center">
<qrcode-vue :value="results.url" :size="size" level="H"></qrcode-vue>
</div>
</b-modal>
and below is my script
<script>
import QrcodeVue from "qrcode.vue";
import axios from "axios";
export default {
data() {
return {
search: "",
results: {},
value: "",
size: 200,
selected: [],
};
},
computed: {
filteredList() {
return this.results.filter(post =>
post.First_Name.toLowerCase().includes(this.search.toLowerCase())
);
}
},
methods: {
getUsers() {
axios
.get("localhost:9000/user/")
.then(response => (this.results = response.data))
.catch(error => console.log(error.message));
}
},
components: {
QrcodeVue
},
mounted() {
this.getUsers();
}
};
</script>
v-for also gives you the index of the item you're on:
<tr v-for="(result, index) in filteredList" :key="result.id">
Then you can just use index === filteredList.length
You can try this:
<tr v-for="result in filteredList.data" :key="result.id">
<td>{{result.Memb_ID}}</td>

Angular 4-Add rows in table

I have this service subscribtion
callSearchService($event) {
this.searchService.searchUser(this.firstName,this.lastName).subscribe(
data => {
console.log("we got: ", data);
this.isNull(data.firstName,data.lastName);
},
error => {
console.log("Error",error);
},
);
and also I have a table .
<thead>
<tr>
<th>#</th>
<th>FirstName</th>
<th>LastName</th>
</tr>
</thead>
I am interested how to add rows dynamically to my table, when i get user info (firstname and lastname) from the callSearchService
something like this
users = []; //user array
<thead>
<tr>
<th>#</th>
<th>FirstName</th>
<th>LastName</th>
</tr>
</thead>
<tbody>
<ng-container *ngFor="let user of users; let i=index;">
<tr>
<th>{{i}}</th>
<td>{{user.firstName}}</td>
<td>{{user.lastName}}</td>
</tr>
</ng-container>
</tbody>
when you receive new user just update array and remaining things will work fine
callSearchService($event) {
this.searchService.searchUser(this.firstName,this.lastName).subscribe(
data => {
console.log("we got: ", data);
this.isNull(data.firstName,data.lastName);
this.users.push(data);
},
error => {
console.log("Error",error);
},
);
You can use ngFor.
suppose you are getting the results in userdetails[] variable.
<tr *ngFor="let userdetail of userdetails | async">
<td>
{{userdetail.firstName}}
</td>
<td>
{{userdetail.lastName}}
</td>
</tr>

Categories

Resources