how to get and display data from firebase realtime database? - javascript

I want to get data from the database. Then change them. And then display.
Please tell me how to solve this problem and why I can not do it.
Here is my code
let firebaseConfig = {...};
firebase.initializeApp(firebaseConfig);
let ref = firebase.database().ref('/data')
class DataTable {
constructor(parent) {
this.parent = parent;
}
buildTable(data) {
this.data = data;
const keys = Object.keys(data[0]);
console.log(keys)
let div = document.createElement('div');
let tab = document.createElement('table');
let tb = document.createElement('tbody');
const buildTableBody = () => {
for (let a of data) {
let tr = document.createElement('tr');
keys.forEach((key) => {
let td = document.createElement('td');
let tn = document.createTextNode(a[key])
td.appendChild(tn);
tr.appendChild(td);
});
tb.appendChild(tr);
}
tab.appendChild(tb);
div.appendChild(tab);
}
this.parent.appendChild(div);
buildTableBody()
}
}
const table = new DataTable(document.body);
table.buildTable(
ref.once("value").then((snap) => {
const data = snap.val()
data.map(i => {
let res = {
'#': Number(i.id),
'Name': i.name,
};
return Object.entries(res).reduce((memo, [key, value]) => {
if (value) {
return {
...memo,
[key]: value
}
} else {
return memo;
}
}, {})
})
}))
But it returns to me Promise {}proto: Promise[[PromiseStatus]]: "resolved"[[PromiseValue]]: undefined

The way you're trying to pass the data into buildTable doesn't work. If you put a breakpoint inside buildTable, you'll be able to see that.
The reason is that the data is loaded from Firebase asynchronously, and any code that needs the data has to be called from inside the once() callback. So you'll want to put the call to buildTable within that callback, like this:
ref.once("value").then((snap) => {
const data = snap.val()
let result = data.map(i => {
let res = {
'#': Number(i.id),
'Name': i.name,
};
return Object.entries(res).reduce((memo, [key, value]) => {
if (value) {
return {
...memo,
[key]: value
}
} else {
return memo;
}
}, {})
})
table.buildTable(result);
}))

Related

pass an argument from axios to a method vue

I'm new to vue and I'm trying to make this work. I get some data from a XML, everything works, but I want to change which value I get from XML using a computed which gets a value from Store.
My computed is:
currentStep: {
set (val) {
this.$store.commit('setCurrentStep', val)
},
get () {
return this.$store.state.currentStep
}
}
With axios and xml2js I get all data with this Method:
getData() {
axios.get("https://something.xml").then((response) => {
this.parseXML(response.data).then((data) => {
this.flightInformations = data
})
})
},
parseXML(data) {
return new Promise((resolve) => {
let parser = new xml2js.Parser({
trim: true,
explicitArray: true,
});
parser.parseString(data, function (err, result) {
let obj = null
obj = result.flugplan.abflug[0].flug;
let flight_dates = {};
for (let item of obj) {
let flight_date = item.datum.join().toString();
if (!flight_dates[flight_date]) {
flight_dates[flight_date] = [];
}
flight_dates[flight_date].push({
flightNr: item.flugnr.join().toString(),
flightPlace: item.ort.join().toString(),
flightPlan: item.plan.join().toString(),
flightExpected: item.erwartet.join().toString(),
flightDate: item.datum.join().toString(),
})
}
resolve(flight_dates);
})
})
}
I need to change my OBJ using my computed like:
let obj = null
if (this.currentStep === 'departures') {
obj = result.flugplan.abflug[0].flug;
} else {
obj = result.flugplan.ankunft[0].flug;
}
But it does not work. Can you guys please help ?
Thank you very much.
Computed can only return some value instead of modifying anything.
Try this one:
computed: {
someData() {
return this.currentStep === 'departures' ? result.flugplan.abflug[0].flug : result.flugplan.ankunft[0].flug;
}
}
After that use a someData value:
const obj = this.someData
I get it finally and now works! here is the code, if someone have the same issue
getData() {
axios.get("something.xml").then((response) => {
this.parseXML(response.data).then((data) => {
this.flightInformations = data
})
.catch(err => {
console.log(`${err} data is not avaiable`)
})
})
},
parseXML(data) {
return new Promise((resolve) => {
let parser = new xml2js.Parser({
trim: true,
explicitArray: true,
});
parser.parseString(data, (err, result) => {
let obj = null
if (this.$store.state.currentStep === 'abflug') {
obj = result.flugplan.abflug[0].flug
} else {
obj = result.flugplan.ankunft[0].flug
}
let flight_dates = {};
for (let item of obj) {
let flight_date = item.datum.join().toString();
if (!flight_dates[flight_date]) {
flight_dates[flight_date] = [];
}
flight_dates[flight_date].push({
flightNr: item.flugnr.join().toString(),
flightPlace: item.ort.join().toString(),
flightPlan: item.plan.join().toString(),
flightExpected: item.erwartet.join().toString(),
flightDate: item.datum.join().toString()
})
}
resolve(flight_dates)
})
})
}
Now using Store, when I change my CurrentStep, it also changes which part of XML it reads.

how to run useEffect only twice

Here is My useEffect is going in Infinite loop, becouse checkimage value is changing becouse the value is assigned in fetch(), so anyone know how to solve it. I want to get varient data with image but I can't get it in first time.
help me if you can
Thank You
useEffect(() => {
fetch({ pagination });
}, [checkimage]);
const fetch = async (params = {}) => {
if (type == 'product') {
dispatch(await ProductService.getProduct(productId))
.then((res) => {
let variantsdatas = getImageArns(res.data.variants);
getImages(variantsdatas);
let record = [];
record.push(res.data)
setVarientsData(record)
})
.catch((err) => {});
} else {
dispatch(await ProductService.getProducts())
.then((res) => {
console.info({ 'res.data': res.data });
setVarientsData(res.data.products);
setPagination({
...params.pagination,
total: res.total_count,
});
})
.catch((err) => {});
}
};
const getImageArns = (variantsdatas) => {
const variantImageArns = [];
variantsdatas.forEach((variant, index) => {
variant[index] = variant.variantId;
if (variant.variantImagesListResponseDto.images.length > 0) {
let variantImageObj = {
variantId: variant.variantId,
arnUrl: variant.variantImagesListResponseDto.images[0].docUrl,
};
variantImageArns.push(variantImageObj);
}
});
// console.info('id', variantImageArns);
return variantImageArns;
};
const getImages = async (variantsdatas) => {
const images = [];
dispatch(await ProductVariantService.getImage(variantsdatas))
.then((res) => {
console.info(res.data.fileResponseDtoList);
let presignedURLs = {};
res.data.fileResponseDtoList.map(
(i) => (
(presignedURLs = {
variantId: i.variantId,
arnUrl: i.presignedURL,
}),
console.info(presignedURLs),
images.push(presignedURLs)
)
);
setcheckimage(images);
})
.catch((err) => {
console.info('Get Error District...');
});
};
var img = 'img';
const setVarientsData = (products) => {
let varients_array = [];
if (products.length > 0) {
products.forEach((product) => {
if (product.variants.length > 0) {
let product_varients = product.variants;
product_varients.forEach((varient) => {
for (var f = 0; f < checkimage.length; f++) {
if(checkimage[f].variantId == varient.variantId){
img = checkimage[f].arnUrl;
f = checkimage.length
}
else{
img = 'img2';
}
}
varients_array.push({
image: img,
variantId: varient.variantId,
productVariantName: varient.variantName,
productName: product.productName,
brand: '-',
sellerSku: varient.productVariantCode,
status: product.status,
category: product.subCategoryInfo.categoryInfo.categoryName,
subCategoryName: product.subCategoryInfo.subCategoryName,
state: '-',
market: '-',
mrp: varient.price.amount + ' ' + varient.price.currency,
sellingPrice: '-',
manufacturer_product_variant_code:
varient.manufacturerProductVariantCode,
product_varient_code: varient.azProductVariantLongCode,
hsnCode: varient.hsnCode,
});
});
}
});
}
setVarients(varients_array);
console.info('varients_array ====>>', {varients_array})
};
I think that if I stop to run blow code getImage function then I can get my result
am I right?
But I tried It too but is also not happening properly.
a quick and dirty fix could be to work with a counter.
and only run the fetch in the useEffect, when counter is 0.
have you tried that?

Vanilla JavaScript search - how to add multiple fields?

This function is searching from a Json data the field "title".
Please, how can I modify this to include multiple fields, like: "tags", "author" etc.? Thanks!
document.addEventListener('DOMContentLoaded', function(event) {
const search = document.getElementById('search');
const results = document.getElementById('results');
let data = [];
let search_term = '';
fetch('/search.json')
.then(response => response.json())
.then(data_server => {
data = data_server;
});
search.addEventListener('input', event => {
search_term = event.target.value.toLowerCase();
showList();
});
const showList = () => {
results.innerHTML = '';
if (search_term.length <= 0) return;
const match = new RegExp(`${search_term}`, 'gi');
let result = data.filter(name => match.test(name.title));
if (result.length == 0) {
const li = document.createElement('li');
li.innerHTML = `No results found 😢`;
results.appendChild(li);
}
result.forEach(e => {
const li = document.createElement('li');
li.innerHTML = `${e.title}`;
results.appendChild(li);
});
};
});
change
let result = data.filter(name => match.test(name.title));
to
let result = data.filter(name => match.test(name.title) || match.test(name.tags) || match.test(name.auther));
It may be an idea to filter on all entries of the objects within the Array retrieved from the json.
Here's a minimal reproducable example, using Event Delegation.
See also
document.addEventListener(`click`, handle);
const data = getJSONFakeData();
function handle(evt) {
if (evt.target.id === `search`) {
return searchJSON();
}
}
function searchJSON() {
const resultsDiv = document.querySelector(`#results`);
resultsDiv.textContent = ``;
const nothingFound = isEmpty =>
resultsDiv.insertAdjacentHTML(
`beforeend`,
`<h3>${isEmpty
? `😢 No input`
: `No results found 😢`}</h3>` );
const term = document.querySelector(`#term`).value.trim();
if (term.length < 1) {
return nothingFound(true);
}
const re = new RegExp(term, `gi`);
// filter here
const results = data
.filter( entry => Object.entries(entry)
.find( ([, value]) => re.test(value) )
);
if (results.length) {
let elems = [];
results.forEach( result => {
const res = Object.entries(result)
.reduce( (acc, [key, value]) =>
acc.concat(`<i>${key}</i>: ${value};<br>`), ``);
elems.push(`<li>${res}</li>`);
});
return resultsDiv.insertAdjacentHTML(
`beforeend`,
`<ul>${elems.join(``)}</ul>`);
}
return nothingFound();
}
function getJSONFakeData() {
return [{
title: `title1`,
author: `author1`,
tags: `science, medicine`,
editor: `Springer Verlag`
},
{
title: `title2`,
author: `author2`,
tags: `automotive, engine`,
editor: `Elsevier`
},
{
title: `title3`,
author: `author3`,
tags: `programming, functional, loops`,
editor: `Elsevier`
},
];
}
body {
font: normal 12px/15px verdana, arial;
margin: 2em;
}
<input type="text" id="term" value="Elsevier">
<button id="search">Find</button>
<div id="results"></div>

Why the default value variable change as the changed variable value, Vuejs

as you see the code, on the handleUpdateFilter function the second "if" some how defaultCourseData is filtered as filteredData of the first "if". Thank you for helping me!
setup() {
const course = ref();
const defaultCourseData = null
const gettingCourse = async () => {
const { data } = await getCourse();
defaultCourseData = data
course.value = data;
};
const handleUpdateFilter = (data) => {
// data is filtering value
if (data.value.view) {
const filteredData = defaultCourseData.sort((a, b) => b.luotXem - a.luotXem);
course.value = filteredData;
}
if (!data.value.view) {
course.value = defaultCourseData // This case some how defaultCourseData filtered too
}
};
onMounted(() => {
gettingCourse();
});
return {
course,
handleUpdateFilter,
defaultCourseData
};
},
Your defaultCourseData variable isn't reactive.
Therefore it should be evaluated as null at every call.
Try this
defineComponent({
setup() {
const course = ref([]);
const defaultCourseData = ref([]);
const gettingCourse = async () => {
const { data } = await getCourse();
defaultCourseData.value = data
course.value = data;
};
const handleUpdateFilter = (data) => {
// data is filtering value
if (data.value.view) {
course.value = defaultCourseData.value.sort((a, b) => b.luotXem - a.luotXem);
}
if (!data.value.view) {
course.value = defaultCourseData.value // This case some how defaultCourseData filtered too
}
};
onMounted(async () => {
await gettingCourse();
});
return {
course,
handleUpdateFilter,
defaultCourseData
};
})
Edit: The actual issue here was, that the defaultCourseData always returned a sorted array as Array.prototype.sort() mutates the Array.
So making a copy solves the issue.
if (data.value.view) { course.value = [...defaultCourseData.value].sort((a, b) => b.luotXem - a.luotXem); }

Vue js/Javascript Objects.assign() not working

I need to concatenate two objects in Vue/Javascript and order the resulting one by date field but I'm getting empty results using Object.assign().
I've tried other methods searching on StackOverflow but nothing has worked as expected. Mostly I get empty results
methods: {
getAllMessages: function () {
// console.log(this.myID);
let distinct = '';
firebase.firestore().collection('private-messages').where('memberID', '==', `${this.myID}`)
.orderBy('date').onSnapshot(res => {
let members = [];
res.forEach(doc => {
members.push(doc.data().uid);
});
distinct = Array.from(new Set(members));
// console.log(distinct);
this.getUserToTalk(distinct);
});
},
getMyMessages: function (memberID) {
let myMessages = [];
firebase.firestore().collection('private-messages').where('uid', '==', `${this.myID}`).where('memberID', '==', `${memberID}`)
.orderBy('date').onSnapshot(res => {
res.forEach(doc => {
myMessages.push(doc.data());
});
});
// this.myMessages = myMessages;
return myMessages;
},
getMessages: function (memberID) {
let messages = [];
firebase.firestore().collection('private-messages').where('uid', '==', `${memberID}`).where('memberID', '==', `${this.myID}`)
.orderBy('date').onSnapshot(res => {
res.forEach(doc => {
messages.push(doc.data());
});
});
// this.memberMessages = messages;
return messages;
},
getUserToTalk: function (memberID) {
axios.post('http://localhost/backend/getMemberToTalk.php', {
"token": token,
"whoToTalkTo": memberID,
}).then(response => {
if (response.data != "Error getting user data and tour") {
let joinedData = []
// console.log(response.data);
response.data.forEach(res => {
let id = res.memberID;
let messages = this.getMessages(id);
// console.log(messages);
let myMessages = this.getMyMessages(id);
// console.log(myMessages);
// if I use below assignment I can get the messages, but I need to concat them.
// so, if I use let conversation = Object.assign({}, messages, myMessages);
// or let conversation = { ...messages, ...myMessages }
// the result is always empty.
let talk1 = Object.assign(messages);
let talk2 = Object.assign(myMessages);
console.log(talk, talkmy);
let data = {
memberID: res.memberID,
memberProfileImg: res.memberProfileImg,
memberName: res.memberName,
memberLastname: res.memberLastname,
memberCity: res.memberCity,
memberState: res.memberState,
memberMessages: messages,
myMessages: myMessages,
// messages: conversation
}
joinedData.push(data);
});
// console.log(joinedData);
this.memberData = joinedData;
// console.log(this.memberData);
} else {
console.log(response.data);
}
}).catch(error => {
console.log(error);
});
},
}
These are the full objects and in the example below I need to add the object from messages.js:140 as a "third index" in messages.js:137 resulting in
0:{...}
1:{...}
2:{...}
and then
3:{...}

Categories

Resources