display all documents from a collection react firebase - reactjs

I have a collection named "journee", and i want to build a list with all elements inside so i get all the data like this :
export async function getAllJournaux() {
const journaux = {};
const querySnapshot = await getDocs(collection(db, "journaux"));
querySnapshot.forEach((doc) => {
// doc.data() is never undefined for query doc snapshots
// console.log(doc.id, " => ", doc.data());
journaux[doc.id] = doc.data();
});
return journaux;
}
Then on my page getIt witn an useEffect like :
const [journaux, setJournaux] = React.useState();
useEffect(() => {
const getJournaux = async () => {
try {
const getJournaux = await getAllJournaux();
setJournaux(getJournaux);
} catch(error) {
// handle any rejections/errors/etc
}
};
getJournaux(); // <-- fetch/compute coupeur value
}, []);
if (!journaux){
console.log("wait"); // or loading indicator/etc
}else{
console.log(journaux);
}
But how to make a list with the data on my screen , for the moment i just access it with console.log.
The outpout of console.log
{
"8SlEz4CslmTMSxWuqB8W2lDICwj22022-05-02": {
"date": "2022-05-02",
"billetage": {
"5": 0,
"10": 0,
"25": 0,
"50": 0,
"100": 0,
"200": 0,
"250": 0,
"500": 0,
"1000": "2",
"2000": "3",
"5000": "4",
"10000": "5"
},
"pt": "3400000",
"at": "30000",
"vt": "450000",
"coupeur": "qKh2entwU7YD0wcxWRI3"
},
"8SlEz4CslmTMSxWuqB8W2lDICwj22022-05-03": {
"at": "555",
"date": "2022-05-03",
"coupeur": "YuYRYzWj4CVidsmAjO1d",
"vt": "334",
"pt": "5555"
},
"KiuU1xQaKWTAx5mt9XL8vBpY3Y822022-03-01": {
"pt": "150000",
"vt": "450000",
"date": "2022-03-01",
"at": "3000",
"billetage": {
"5": "5",
"10": "3",
"25": "5",
"50": "1",
"100": "2",
"200": "4",
"250": "2",
"500": "3",
"1000": "6",
"2000": "3",
"5000": "4",
"10000": "2"
},
"coupeur": "Ad5g5AE2HdqbZGzhu7G5"
},
"KiuU1xQaKWTAx5mt9XL8vBpY3Y822022-05-11": {
"coupeur": "qKh2entwU7YD0wcxWRI3",
"billetage": {
"5": 0,
"10": 0,
"25": 0,
"50": 0,
"100": 0,
"200": 0,
"250": 0,
"500": 0,
"1000": 0,
"2000": "5",
"5000": "3",
"10000": "10"
},
"pt": "30000",
"date": "2022-05-11",
"at": "100",
"vt": "200000"
},
"KiuU1xQaKWTAx5mt9XL8vBpY3Y822022-05-23T14:03": {
"date": "2022-05-23T14:03",
"pt": "50000",
"coupeur": "",
"at": "130000",
"vt": "200000",
"billetage": {
"5": 0,
"10": 0,
"25": 0,
"50": 0,
"100": 0,
"200": 0,
"250": 0,
"500": 0,
"1000": 0,
"2000": "3",
"5000": "5",
"10000": "2"
}
}
}
Thank you

getAllJournaux is returning an object, so you have to use Object.keys to iterate
const Component = () => {
const [journaux, setJournaux] = useState();
useEffect(() => {
const getJournaux = async () => {
try {
const getJournaux = await getAllJournaux();
setJournaux(getJournaux);
} catch (error) {}
};
getJournaux();
}, []);
return <ul>
{Object.keys(journaux || {}).map(item => (
<li>{item.coupeur}</li>
))}
</ul>
};

const Component = () => {
const [journaux, setJournaux] = useState();
useEffect(() => {
const getJournaux = async () => {
try {
const getJournaux = await getAllJournaux();
setJournaux(getJournaux);
} catch (error) {}
};
getJournaux();
}, []);
// Change .prop1 to a property found in each object of the list
return <ul>
{(journaux || []).map(item => (
<li>{item.prop1}</li>
))}
</ul>
};

Related

ReactHook adding array of an array state without duplicating the key

I am trying to add data grouping by the unit name for showing functionality
const [allData , setAllData]= useState([{'unit':'' , data:[]}])
useEffect(async () => {
await axios.get(`${BACKEND_URL}/data`).then(res => {
res.data.map(elem => {
setAllData(prev =>[...prev , { 'unit': elem.unitName, 'data': [elem.lessonName] }]);
});
});
}, []);
the result is duplicating the key for the subarray which is "unit" for my exampl:
[
{
"unit": "unit 1",
"data": [
"LO1"
]
},
{
"unit": "unit 2",
"data": [
"LO2"
]
},
{
"unit": "unit 3",
"data": [
"LO3"
]
},
{
"unit": "unit 1",
"data": [
"LO15"
]
}
]
Try like that, if find unique property unit rewrite data or push new element to array
useEffect(async () => {
await axios.get(`${BACKEND_URL}/data`).then(res => {
setAllData((prev) => {
let result = [...prev];
res.data.forEach(({ unitName: unit, lessonName }) => {
const index = result.findIndex((elem) => elem.unit === unit);
if (index >= 0) {
result[index].data = [...result[index].data, lessonName]
} else {
result.push({unit, data: [lessonName]});
}
});
return result;
});
});
}, []);

React typescript hashmap title as key and values inside

I'm trying to display multiple items belonging to one element, i.e values belonging to key. The key in this case is the title like
Electronics
prod1
prod2
prod3
Home Appliance
prod4
prod5
prod6
So I have a type with an array of elements, one of the elements is the title, while the other elements are displayed under
enum ProductCatagory {
Electronics = "Electronics" ,
HomeAppliance = "HomeAppliance"
}
export type Product= {
pId: number,
productName: string
}
type MyHashMap= {
[id: string] : items[]
}
function ProductClass() {
const myHash: MyHashMap= {}
const obj: Product= {
"0": { "pId": 0, "productName": "prod1", "catagory": "Home Appliance" },
"1": { "pId": 1, "productName": "prod2", "catagory": "Home Appliance" },
"2": { "pId": 2, "productName": "prod3", "catagory": "Home Appliance" }
"3": { "pId": 3, "productName": "prod1", "catagory": "Electronics" },
"4": { "pId": 4, "productName": "prod2", "catagory": "Electronics" },
"5": { "pId": 5, "productName": "prod3", "catagory": "Electronics" }
};
obj.map(s => {
if (!myHash[s.catagory]) {
myHash[s.catagory] = []
}
myHash[s.catagory].push(s)
})
const electronics= obj[ProductCatagory.Electronics].map(e => { return e} );
const homeAppliance= obj[ProductCatagory.HomeAppliance].map(h => { return h} );
const differentiator = (electronics||homeAppliance) : (electronics|| homeAppliance)
return (
{<h1>{titlehere}</h1>
<ul>
{
differentiator.map((prod, key) => {
return (
<h1 key={key}>{prod}</h1>
)
})
}
</ul>
)
}
What I have tried so far is using switch statement, but I just don't know how to print out only the key in the title and products underneath. But I need help with how, or any pointers would help.
I figured it out for anyone interested.
https://reactjs.org/docs/lists-and-keys.html
So the answer would be
enum ProductCatagory {
Electronics = "Electronics" ,
HomeAppliance = "HomeAppliance"
}
export type Product= {
pId: number,
productName: string
}
type MyHashMap= {
[id: string] : items[]
}
function ProductClass() {
const myHash: MyHashMap= {}
const obj: Product= {
"0": { "pId": 0, "productName": "prod1", "catagory": "Home Appliance" },
"1": { "pId": 1, "productName": "prod2", "catagory": "Home Appliance" },
"2": { "pId": 2, "productName": "prod3", "catagory": "Home Appliance" }
"3": { "pId": 3, "productName": "prod1", "catagory": "Electronics" },
"4": { "pId": 4, "productName": "prod2", "catagory": "Electronics" },
"5": { "pId": 5, "productName": "prod3", "catagory": "Electronics" }
};
obj.map(s => {
if (!myHash[s.catagory]) {
myHash[s.catagory] = []
}
myHash[s.catagory].push(s)
})
const electronics= obj[ProductCatagory.Electronics].map(e => { return e} );
const homeAppliance= obj[ProductCatagory.HomeAppliance].map(h => { return h} );
const differentiator = (electronics||homeAppliance) : (electronics|| homeAppliance)
const renderProducts= Object.entries(myHash).map(([catagory, productName], key) => {
return (
<divkey={key}>
<h3>{catagory}</h3>
<p>{productName.map(p => {return p.productName})}</p>
</div>
)
})
return (
<>
{renderProducts}
</>
);
}

How do I sort this array by date?

I'm trying to sort the dates from this external API in my latestResults array by latest on top to oldest on bottom but can't seem to figure out how.
Right now they're displayed with the oldest date first and it's working fine, but it's in the wrong order for me.
I tried using result in latestResults.reverse() but that just reverses the 7 items currently in the array.
HTML:
<div v-for="result in latestResults" v-bind:key="result.latestResults">
<small">{{ result.utcDate }}</small>
</div>
Script:
<script>
import api from '../api'
export default {
data () {
return {
latestResults: [],
limit: 7,
busy: false,
loader: false,
}
},
methods: {
loadMore() {
this.loader = true;
this.busy = true;
api.get('competitions/PL/matches?status=FINISHED')
.then(response => { const append = response.data.matches.slice(
this.latestResults.length,
this.latestResults.length + this.limit,
this.latestResults.sort((b, a) => {
return new Date(b.utcDate) - new Date(a.utcDate);
})
);
setTimeout(() => {
this.latestResults = this.latestResults.concat(append);
this.busy = false;
this.loader = false;
}, 500);
});
}
},
created() {
this.loadMore();
}
}
</script>
The JSON where I'm getting matches like this that has utcDate:
{
"count": 205,
"filters": {
"status": [
"FINISHED"
]
},
"competition": {
"id": 2021,
"area": {
"id": 2072,
"name": "England"
},
"name": "Premier League",
"code": "PL",
"plan": "TIER_ONE",
"lastUpdated": "2021-02-01T16:20:10Z"
},
"matches": [
{
"id": 303759,
"season": {
"id": 619,
"startDate": "2020-09-12",
"endDate": "2021-05-23",
"currentMatchday": 22
},
"utcDate": "2020-09-12T11:30:00Z",
"status": "FINISHED",
"matchday": 1,
"stage": "REGULAR_SEASON",
"group": "Regular Season",
"lastUpdated": "2020-09-13T00:08:13Z",
"odds": {
"msg": "Activate Odds-Package in User-Panel to retrieve odds."
},
},

arr.findIndex() returns -1

I'm afraid it should be obvious since my affair is based on normal Vanille JS. Anyhow, for any reason I cannot get my issue fixed. Anyhone who can help me out?
Snapshot of my code in reducer:
> case TOGGLE_PRODUCT:
> const newProducts = [...state.allProducts];
> console.log("All products: ", newProducts);
> console.log("Passed product: ", action.productId);
> console.log("Should have found: ", newProducts[1]);
> const toggledProduct = newProducts.findIndex(
> (el) => el.id === action.productId
> );
> console.log("Found: ", toggledProduct);
Output in console:
All products: Array [
Product {
"amount": 0,
"department": "Molkereiprodukte",
"id": "id1",
"product": "Milch 3,5%",
"status": false,
},
Product {
"amount": 0,
"department": "Molkereiprodukte",
"id": "id2",
"product": "Yoghurt",
"status": false,
},
Product {
"amount": 0,
"department": "Ceralien",
"id": "id3",
"product": "Müsli",
"status": false,
},
]
Passed product: Object {
"id": "id2",
}
Should have found: Product {
"amount": 0,
"department": "Molkereiprodukte",
"id": "id2",
"product": "Yoghurt",
"status": false,
}
Found: -1
Why does the find() method not return a result???
Thx in Advance!
your action.productId is an objectnot a string
const toggledProduct = newProducts.findIndex(
(el) => el.id === action.productId.id /** <--here */
);
findIndex is used to find desire index of the element you need Array.find to get element data. Reason you are getting -1 is because action.productId is an object. You need to compare action.productId.id
const toggledProduct = newProducts.find(el => el.id === action.productId.id );

setItem in AsyncStorage doesn't work

I'm trying to upload some data to the server from React Native. The data is stored in AsyncStorage.
The data is as follows :
let vehicles = [
{
"id": 1,
"make_text": "Peugeot",
"model_text": "208",
"color_text": "Argent",
"category_text": "CT",
"tag_text": "",
"vin": "123456",
"registration": "",
"reference": "",
"comment": "",
"autralis_id": 151390
},
{
"id": 1,
"make_text": "Peugeot",
"model_text": "307",
"color_text": "Bleu",
"category_text": "CT",
"tag_text": "",
"vin": "654321",
"registration": "",
"reference": "",
"comment": "",
"autralis_id": 156413
}
]
And
let vehicle_slots = [
{
"vehicle_id": 1,
"slot_id": 118,
"area": "",
"zone": "B",
"aisle": "",
"side": "S",
"col": 2,
"level": 0,
"position": 0,
"timestamp": "201705021544",
"picturepath": "",
"pictureguid": "0a016bb9-b7bb-4dd7-a0bf-407ef31a0c1a",
"reason": "ENTER",
"handled": 0,
"uploaded": 0
},
{
"vehicle_id": 1,
"slot_id": 2521,
"area": "",
"zone": "C",
"aisle": "",
"side": "E",
"col": 4,
"level": 0,
"position": 0,
"timestamp": "201705021544",
"picturepath": "",
"pictureguid": "64c726e2-37ec-4ab7-8b57-b08e9899086a",
"reason": "ENTER",
"handled": 0,
"uploaded": 0
}
]
I want to send only those which have uploaded and handled property equals to 0.
Thus, first I get those values where uploaded and handled property is equal to 0. I do it as follows:
try {
let vehicle_data = await AsyncStorage.getItem('vehicle');
if (vehicle_data !== null){
// We have data!!
let vehicle_slot_data = await AsyncStorage.getItem('vehicle_slot');
if (vehicle_slot_data !== null){
vehicle_data = JSON.parse(vehicle_data);
vehicle_slot_data = JSON.parse(vehicle_slot_data);
let result_to_handle = [];
let result_to_upload = [];
vehicle_slot_data.forEach(v => {
let not_handled = vehicle_data.find(m => m.id === v.vehicle_id && v.handled === 0);
let not_uploaded = vehicle_data.find(m => m.id === v.vehicle_id && v.uploaded === 0);
if ( not_uploaded ) result_to_upload.push(that.renderData(v, not_uploaded)[0]);
if ( not_handled ) result_to_handle.push(that.renderData(v, not_handled)[0]);
});
//Here I have result_to_handle and result_to_upload with the data that I need to send to the server.
............
If result_to_handle and result_to_upload have length > 0 then I want to send them to the server and update the property handled and property uploaded to 1 in AsyncStorage.
I try to do it as follows :
..............
if (result_to_handle.length > 0){
let options = {
method: 'POST',
body: JSON.stringify(result_to_handle),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
};
fetch(data_url + "/manager/transport/sync/movements/", options)
.then(response => response.json())
.then(responseData => {
AsyncStorage.getItem('vehicle_slot')
.then(json => {
let data = [];
if (json) data = JSON.parse(json);
let result = [];
forEach(data, value => {
if( value.handled === 0 ){
value.handled = 1;
result.push(value);
}else{
result.push(value);
}
});
AsyncStorage.setItem('vehicle_slot', JSON.stringify(result))
});
});
}
if (result_to_upload.length > 0){
forEach(result_to_upload, value => {
if (value.picturepath) {
let body = new FormData();
const photo = {
uri: value.picturepath,
type: 'image/jpeg',
name: value.pictureguid + '.jpg',
};
body.append('image', photo);
let xhr = new XMLHttpRequest();
xhr.open('POST', data_url + "/manager/transport/sync/picture/?pictureguid=" + value.pictureguid);
xhr.onload = (e) => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
AsyncStorage.getItem('vehicle_slot')
.then(json => {
if (json){
let data = JSON.parse(json);
let result_data = [];
forEach(data, val => {
if( val.pictureguid === value.pictureguid ){
val.uploaded = 1;
result_data.push(val);
}else{
result_data.push(val);
}
});
AsyncStorage.setItem('vehicle_slot', JSON.stringify(result_data), () => s_cb())
}
});
}
}
};
xhr.onerror = (e) => console.log('Error');
xhr.send(body);
} else {
AsyncStorage.getItem('vehicle_slot')
.then(json => {
if (json){
let data = JSON.parse(json);
let result_data = [];
forEach(data, val => {
if( val.pictureguid === value.pictureguid ){
val.uploaded = 1;
result_data.push(val);
}else{
result_data.push(val);
}
});
AsyncStorage.setItem('vehicle_slot', JSON.stringify(result_data), () => s_cb())
}
});
}
});
}
But the result that I get is not correct.
The vehicle_slot from AsyncStorage is as follows:
[
{
"vehicle_id": 1,
"slot_id": 118,
"area": "",
"zone": "B",
"aisle": "",
"side": "S",
"col": 2,
"level": 0,
"position": 0,
"timestamp": "201705021544",
"picturepath": "",
"pictureguid": "0a016bb9-b7bb-4dd7-a0bf-407ef31a0c1a",
"reason": "ENTER",
"handled": 1,
"uploaded": 0
},
{
"vehicle_id": 1,
"slot_id": 2521,
"area": "",
"zone": "C",
"aisle": "",
"side": "E",
"col": 4,
"level": 0,
"position": 0,
"timestamp": "201705021544",
"picturepath": "",
"pictureguid": "64c726e2-37ec-4ab7-8b57-b08e9899086a",
"reason": "ENTER",
"handled": 1,
"uploaded": 1
}
]
Thus, for the first object is the value uploaded still equal to 0 but it should be equal to 1.
Any advice?

Resources