Why i cant delete data from arrays more than one? React Native - react-native

I want to delete item from array object base of selected checkboxes. But when I try to delete by id, it's only delete one object.
const [datas, setData] = useState([]); <-- i already setData(Data)
const deleteItemById = (id) => { << ----------- Something wrong with this code
const filteredData = datas.filter(item => item.id !== id);
setData(filteredData);
console.log(datas)
}
const selectedID = () =>{
--- Some API Post Method ---
--- example id_kunjungan is array and contain ["1","2"] from selected checbox
for (var i = 0; i < id_kunjungan.length; i++){
deleteItemById(id_kunjungan?.[i]) <<------- this return the id
console.log(id_kunjungan?.[i])
}
}
const Data= [
{
"start": "2022-01-01 10:35:08",
"id": "1",
"tanggal": "01-01-2022",
"hari": "Saturday",
},
{
"start": "2022-01-01 10:35:08",
"id": "2",
"tanggal": "01-01-2022",
"hari": "Saturday",
},
{
"start": "2022-01-01 10:35:08",
"id": "3",
"tanggal": "01-01-2022",
"hari": "Saturday",
},
{
"start": "2022-01-01 10:35:08",
"id": "4",
"tanggal": "01-01-2022",
"hari": "Saturday",
},
];
I already check for loop its run 2 times but the id[2] is not deleted, it only deletes the first id, not the second or third or more. Why this is happened? Or what is wrong with my code?

This is your code and you are using a for-loop to update the state, which mean states may not be updated correctly since you are updating states many times at one go, overwriting each update.
// This code is wrong ❌
for (var i = 0; i < id_kunjungan.length; i++){
deleteItemById(id_kunjungan?.[i]) // you are calling setDatas multiple times here which is wrong.
console.log(id_kunjungan?.[i])
}
You can try doing just
deleteItemByIds(id_kunjungan) // <--- send the entire array of Ids
Then modify your deleteItemByIds function to remove all items whose id matches.
const deleteItemByIds = (ids = []) => { // <<-- array of ids e.g. [1,2,3,4,5]
const filteredData = datas.filter(item => !ids.includes(item.id);
setData(filteredData);
// console.log(datas) // <--- ❌ Remove this. this will not give u the latest state because state updating is async
}
If you want to see the state change, add a useEffect block.
useEffect(() => {
console.log('datas', datas); //console log whenever datas changes.
}, [datas])

Try this
const Data= [
{
"start": "2022-01-01 10:35:08",
"id": "1",
"tanggal": "01-01-2022",
"hari": "Saturday",
},
{
"start": "2022-01-01 10:35:08",
"id": "2",
"tanggal": "01-01-2022",
"hari": "Saturday",
},
{
"start": "2022-01-01 10:35:08",
"id": "3",
"tanggal": "01-01-2022",
"hari": "Saturday",
},
{
"start": "2022-01-01 10:35:08",
"id": "4",
"tanggal": "01-01-2022",
"hari": "Saturday",
},
];
const deleteItems = (idsToDelete) => {
const newData = Data.filter((item) => {
return !idsToDelete.includes(item.id)
})
return newData
}
console.log(deleteItems(['1','2'])) // <--- pass the ids to delete here

Using Splice make it easier. Using id for finding index of array, and splice it.
const deleteItemById = (id) => {
setData((prevState) =>{
const index = prevState.map(function(x) {return x.id; }).indexOf(id);
const filteredData = prevState.splice(index, 1);
return [...prevState]
})
}

Related

How to break line in vue-multiselect on options

Actually my main problem is about putting breakline inside options in javascript. I've problem with to break line on options when using multiselect with Vue.js.
Multiselect looks like this:
<multiselect v-model="form4.user_id"
:options="users"
:searchable="true"
:preselect-first="true"
:loading="is_loading_customers"
:internal-search="false"
:custom-label="with_customer_custom_label"
#search-change="get_customers_data"
track-by="id"
selected-label=""
select-label=""
deselect-label=""
placeholder="Ad, soyad, TC veya telefon numarası ile aratın..."
id="folder-status-select">
</multiselect>
My with_customer_custom_label function:
const with_customer_custom_label = ({ customer_detail }) => {
return `
TC: ${customer_detail.tc_identity_number} |
Ad Soyad: ${customer_detail.fullname} |
Telefon: ${customer_detail.phone}
`;
};
Options (users):
const users = ref([]);
// and then...
const get_customers_data = (query) => {
if (query.length > 2) {
is_loading_customers.value = true;
var axios_params = new URLSearchParams();
axios_params.append('query', query);
store.state.ax_req_auth.get('/search-customers', {
params: axios_params,
}).then(response => {
users.value = response.data;
is_loading_customers.value = false;
}).catch(error => {
console.log(error);
is_loading_customers.value = false;
});
}
};
response.data return example:
{
"id": "9832a4c7-38cb-4422-a8f3-18f024f31653",
"username": "customer",
"email": "customer#ferisoft.com",
"user_type": "4",
"status": "1",
"email_verified": "1",
"email_verified_at": "2023-01-11T10:26:43.000000Z",
"created_at": "2023-01-11T10:26:43.000000Z",
"updated_at": "2023-01-11T10:26:43.000000Z",
"customer_detail": {
"id": "9832a4c7-c4fe-4f4c-98b9-ab55c9e40265",
"user_id": "9832a4c7-38cb-4422-a8f3-18f024f31653",
"name": "Semih",
"surname": "ŞAHİN",
"tc_identity_number": "99999999990",
"phone": "05555555555",
"date_of_birth": "2023-01-11 10:26:43",
"profession": "0",
"salary": 22500,
"premium": 4000,
"start_date_of_work": "2023-01-11 10:26:43",
"close_to_customer_name": "Ferkan",
"close_to_customer_surname": "AKYAZICI",
"close_to_customer_tc_identity_number": "98989999992",
"close_to_customer_phone": "05527516134",
"email_address": "semih#ferisoft.com",
"profile_picture": null,
"notes": "Krediye şu şu şu sebeplerden dolayı ihtiyacım var, şu şu şu banka geçmişim var.",
"created_at": "2023-01-11T10:26:43.000000Z",
"updated_at": "2023-01-11T10:26:43.000000Z",
"fullname": "Semih ŞAHİN"
}
}
I want to embed with break line the option element to multiselect in the with_customer_custom_label function.
I already tried these:
return `
TC: ${customer_detail.tc_identity_number}\n
Ad Soyad: ${customer_detail.fullname}\n
Telefon: ${customer_detail.phone}
`;
or
return `
TC: ${customer_detail.tc_identity_number}` + "\n" + `
Ad Soyad: ${customer_detail.fullname}` + "\n" + `
Telefon: ${customer_detail.phone}
`;
But they always appear side by side. How can I show one under the other or with break line?

Lodash: filter multiple properties

I am new to lodash.
I am having trouble filtering with lodash. I have a deep nested json object that I want to filter if productName = 'Lotto' and the board selectionMethod = "AUTOPICK"
When I try the solution below, it returns all results instead of filtering. I have tried multiple ways to do this but I always get all results returning.
Could anyone offer a suggestion?
var results = {
"buyTicketDetails": {
"result": 0,
"message": "Success",
"product": [
{
"productName": "Lotto",
"displayPromoMessage": false,
"drawDetails": [
{
"drawTypeDescription": "REGULAR DRAW",
"drawAttribute": "EVENING",
"drawStartDate": "2019-01-12T00:00:00.000-05",
"drawEndDate": "2019-01-12T00:00:00.000-05"
},
{
"drawTypeDescription": "SPECIAL DRAW",
"drawAttribute": "EVENING",
"drawStartDate": "2019-01-12T00:00:00.000-05",
"drawEndDate": "2019-01-12T00:00:00.000-05"
}
],
"board": [
{
"boardType": "REGULAR",
"selectionMethod": "AUTOPICK",
"selectionSet": [
"2",
"4",
"10",
"12",
"17",
"31"
]
},
{
"boardType": "RAFFLE",
"selectionMethod": "SYSTEMPICK",
"selectionSet": [
"40001722-01"
]
}
]
},
{
"productName": "Encore",
"displayPromoMessage": false,
"drawDetails": [
{
"drawTypeDescription": "REGULAR DRAW",
"drawAttribute": "EVENING",
"drawStartDate": "2019-01-12T00:00:00.000-05",
"drawEndDate": "2019-01-12T00:00:00.000-05"
}
],
"board": [
{
"boardType": "REGULAR",
"selectionMethod": "SYSTEMPICK",
"selectionSet": [
"3440514"
]
}
]
}
]
}
}
const filterCat = _.filter(results, { product: [
{
productName: "Lotto",
board: {
selectionMethod: "AUTOPICK"
}}
]
}
);
console.log(filterCat);
With Pure JS.
You can do this with Javascript's filter function too.
filter function actually works on Arrays, so we use map loop to add objects into arrays first, then we use filter function to get only the data we need!.
let Product = results.buyTicketDetails.product
let getSelectionMethods=(index) => Product[index].board.map((d,i)=>d.selectionMethod)
let getTargetedProducts =(Name,Method)=> Product.map((d,i)=>{
if(Product[i].productName==Name && getselectionMethods(i).indexOf(Method) !==-1){
return d
}
})
let FilteredProducts = getTargetedProducts("Lotto","AUTOPICK").filter((d)=>d !==undefined)
console.log(FilteredProducts)

How could I render a ExtWebComponent Area Chart using Alpha Vantage stock data?

I would like to use Alpha Vanatage stock data in my ExtWebComponent chart. How could I fetch the data and render it in a Cartesian Area chart?
If you've generated an ExtWebComponents project, you could add these 2 files and declare the web component html element tag.
Usage
In the html file like index.html declare my-chart-area which is defined in the web component below.
AreaChartComponent.html - HTML Template
<ext-cartesian
width="1000px"
height="600px"
downloadServerUrl="http://svg.sencha.io"
shadow="true"
insetPadding="25 35 0 10"
axes='[{
"type": "numeric" ,
"position": "left" ,
"fields": [ "1. open" ],
"label": { "rotate": { "degrees": "-30" } },
"grid": { "odd": { "fill": "#e8e8e8" } },
"title": { "text": "Alphabet Inc Stock Data" , "fontSize": "20" }
},
{
"type": "category",
"position": "bottom",
"fields": "time",
"grid": "true",
"title": { "text": "Monthly", "fontSize": "20" }
}]'
legend='{
"type": "sprite",
"position": "bottom"
}'
series='[{
"type": "area" ,
"xField": "time",
"yField": [ "1. open", "2. high", "3. low", "4. close" ],
"title": [ "open", "high", "low", "close" ],
"style": { "stroke": "black" , "lineWidth": "2", "fillOpacity": "0.8" },
"colors": ["#003f5c", "#58508d", "#bc5090", "#ff6361", "#ffa600"]
}]'
platformConfig='{
"phone": { "insetPadding": "15 5 0 0" }
}'>
</ext-cartesian>
AreaChartComponent.js - Web Component
import template from './AreaChartComponent.html'
Ext.require([
'Ext.chart.theme.Midnight',
'Ext.chart.theme.Green',
'Ext.chart.theme.Muted',
'Ext.chart.theme.Purple',
'Ext.chart.theme.Sky',
'Ext.chart.series.Area',
'Ext.chart.axis.Numeric',
'Ext.chart.axis.Category'
]);
class AreaChartComponent extends HTMLElement {
constructor() {
super()
}
connectedCallback() {
this.innerHTML = template;
this._fetchChartData();
}
disconnectedCallback() {
}
attributeChangedCallback(attrName, oldVal, newVal) {
}
/**
* Fetch the chart data from https://www.alphavantage.co/ using an API Key.
*
* TODO Fetch your api key here: https://www.alphavantage.co/support/#api-key
*/
_fetchChartData() {
let me = this;
let apiKey = 'demo';
let stockSymbol = 'GOOGL';
let url = `https://www.alphavantage.co/query?function=TIME_SERIES_MONTHLY&symbol=${stockSymbol}&apikey=${apiKey}`;
fetch(url)
.then(response => {
return response.json();
})
.then(json => {
return me._flattenData(json);
})
.then(jsonflatRows => {
me._renderChart(jsonflatRows);
})
.catch(err => {
console.log("error", err);
})
}
/**
* The goal is to flatten the nested json data, so it's easy to consume in the charts.
* #param json data
* #returns {*[]} array of json data
* #private
*/
_flattenData(json) {
console.log("json=", json);
let jsonTimes = json['Monthly Time Series']
let flatRows = [];
for (let jsonTime in jsonTimes) {
let row = {
"time": jsonTime
};
let jsonNestedTime = jsonTimes[jsonTime];
for (let nestedKey in jsonNestedTime) {
row[nestedKey] = jsonNestedTime[nestedKey];
}
flatRows.push(row);
}
return flatRows.reverse();
}
_renderChart(jsonflatRows) {
console.log('_renderChart jsonflatRows=', jsonflatRows);
let store = Ext.create('Ext.data.Store', {
fields: ["time", "1. open", "2. high", "3. low", "4. close", "5. volume"]
});
store.loadData(jsonflatRows);
let areaChartEl = this.querySelector('ext-cartesian');
areaChartEl.ext.bindStore(store);
}
}
window.customElements.define('my-chart-area', AreaChartComponent);
Source
https://gist.github.com/branflake2267/4652a5d7188dfe0b33d3d02a808d8d74

Unable to loop through data from SQLite call in React Native, Expo

I'm currently making a call to an SQLite local database in my react native
Expo app like so:
db.transaction(tx => {
tx.executeSql('select * from dr_report_templates', [], (_, { rows }) => {
const templateData = JSON.stringify(rows);
this.setState({ options: templateData, isLoading: false }, () => console.log(this.state))
});
},
error => {
alert(error);
},
() => console.log('Loaded template settings')
);
I'm returning the data and making it a JSON string with: JSON.stringify
Data appears like so:
Object {
"isLoading": false,
"options": "{\"_array\":[{\"id\":30,\"name\":\"SFR General\",\"description\":\"SFR1\"},{\"id\":31,\"name\":\"SFR Extended\",\"description\":\"SFR2\"},{\"id\":7790,\"name\":\"test_new_template\",\"description\":\"test_new_template\"},{\"id\":7792,\"name\":\"apart_1\",\"description\":\"apart_1\"},{\"id\":7793,\"name\":\"SFR\",\"description\":\"Single Family\"},{\"id\":7798,\"name\":\"Condo\",\"description\":\"Condo \"},{\"id\":7799,\"name\":\"Duplex\",\"description\":\"Duplex\"},{\"id\":7800,\"name\":\"Triplex \",\"description\":\"3\"},{\"id\":7801,\"name\":\"Apartments\",\"description\":\"Apartment complex\"},{\"id\":7802,\"name\":\"Commercial retail store \",\"description\":\"Storefront \"},{\"id\":7803,\"name\":\"5-10 unit\",\"description\":\"5\"},{\"id\":7804,\"name\":\"Commercial Industrial \",\"description\":\"Industrial \"},{\"id\":7805,\"name\":\"Industrial Property\",\"description\":\"RE\"}],\"length\":13}",
"selected": "",
}
Attempting to get values for just the first array element like so:
this.state.options[0]
does not work. I'm obviously doing something wrong in the way that I'm doing this but can't figure out what. Any ideas?
EDIT: I had also ran the query with out JSON.Stringify. The data returned like so with this "t" in front of it. I've never hard this before and I couldn't loop through it so that's why I did a JSON.stringify.
t {
"_array": Array [
Object {
"description": "SFR1",
"id": 30,
"name": "SFR General",
},
Object {
"description": "SFR2",
"id": 31,
"name": "SFR Extended",
},
Object {
"description": "test_new_template",
"id": 7790,
"name": "test_new_template",
},
Object {
"description": "apart_1",
"id": 7792,
"name": "apart_1",
},
Object {
"description": "Single Family",
"id": 7793,
"name": "SFR",
},
Object {
"description": "Condo ",
"id": 7798,
"name": "Condo",
},
Object {
"description": "Duplex",
"id": 7799,
"name": "Duplex",
},
Object {
"description": "3",
"id": 7800,
"name": "Triplex ",
},
Object {
"description": "Apartment complex",
"id": 7801,
"name": "Apartments",
},
Object {
"description": "Storefront ",
"id": 7802,
"name": "Commercial retail store ",
},
Object {
"description": "5",
"id": 7803,
"name": "5-10 unit",
},
Object {
"description": "Industrial ",
"id": 7804,
"name": "Commercial Industrial ",
},
Object {
"description": "RE",
"id": 7805,
"name": "Industrial Property",
},
],
"length": 13,
}
this.setState({ options: templateData._array, isLoading: false });
or change how you destructure in 3rd parameter of executeSql to:
(_, { rows: { _array } }) => {
const templateData = JSON.stringify(_array);
}
Why you're conveting it with JSON.stringify()? You can iterate over array or access it with array's key name.
NOTE: JSON.stringify() does not convert it to JSON. It converts to JSON string
The JSON.stringify() method converts a JavaScript object or value to a
JSON string, optionally replacing values if a replacer function is
specified or optionally including only the specified properties if a
replacer array is specified.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
You're actually converting your database response to string.
So Change
const templateData = JSON.stringify(rows);
to
const templateData = rows;
and use this array where you want.

Use object instead of array in datatables

When using datatables, I get 'no data available in table' when using an object instead of array:
var data1 =
{
"status": "success",
"districts": {
"1": {
"district_number": "1",
"district_name": "district one"
},
"2": {
"district_number": "2",
"district_name": "district two"
}
},
"time": "1.109s"
};
var table1 = jQuery("#data_table1").DataTable({
"data": data1.districts,
"aoColumns": [
{ "mData": "district_number" },
{ "mData": "district_name" }
]
});
I can get an array to display in a datatable using mData as follows:
var data2 =
{
"status": "success",
"districts": [
{
"district_number": "1",
"district_name": "district one"
},
{
"district_number": "2",
"district_name": "district two"
}
],
"time": "1.109s"
};
var table2 = jQuery("#data_table2").DataTable({
"data": data2.districts,
"aoColumns": [
{ "mData": "district_number" },
{ "mData": "district_name" }
]
});
https://jsfiddle.net/w93gubLv/
Is there a way to get datatables to utilize the object in the original format, or must I convert the object to an array?
You can write your own function to convert one format to another, for example:
function formatData(data){
var result = [];
for(prop in data){
if(data.hasOwnProperty(prop)){
result.push( data[prop] );
}
}
return result;
}
You can then later use it to pass data to jQuery DataTables as shown below.
var table1 = jQuery("#data_table1").DataTable({
"data": formatData(data1.districts),
"aoColumns": [
{ "mData": "district_number" },
{ "mData": "district_name" }
]
});
See updated jsFiddle for code and demonstration.