Firebase not saving data? - javascript

I'm trying to scrape a webpage, and save the data to Firebase. I can console.log the data, but I can't get it to save. At first I thought the tabletojson function took a second to grab the data, so I decided to put the Firebase part where I save data into a separate function.
When I run this in the terminal, the console.log doesn't appear because something is going wrong with saving the data to Firebase. Any ideas on how to fix this script?
var tabletojson = require('tabletojson');
var Firebase = require('firebase')
var url = 'https://en.wikipedia.org/wiki/List_of_sovereign_states#List_of_states';
tabletojson.convertUrl(url, function(tablesAsJson) {
var listofSovereignStates = tablesAsJson[0];
sendToFirebase(listofSovereignStates)
});
function sendToFirebase(data) {
dataRef = new Firebase("https://mikesweather.firebaseio.com/flags")
dataRef.set(data)
console.log(data)
}

Try this:
function sendToFirebase(data) {
var dataRef = new Firebase("https://mikesweather.firebaseio.com/flags")
dataRef.set({myData: data})
console.log(data)
}
Per the example below you can see that you need to pass in an object to set:
dataRef.set({
alanisawesome: {
date_of_birth: "June 23, 1912",
full_name: "Alan Turing"
}
});
https://www.firebase.com/docs/web/guide/saving-data.html
Edit, after thinking about it, it is possible this is not the solution, let me know if this works...

Related

Import Json data in a JS variable simply

I made a js with data in a const array as below
const messages = [
{ date: '2020-1-1', content:'message1'},
]
In order to make my file cleaner I decide to put the data in a Json file and want to call the Data in my Js in order to use it like before.
my Json is like this
[
{
"date":"2020-1-1",
"content":"message1"
}
]
In order to import my Json I put this code:
let messages = [];
$.getJSON("messages.json", function(data) {
messages = data;
console.log(messages);
});
The result is that my array is loaded in the console but the variable dont work, I tried things with Object.keys but no more result. I dont use framework also and dont find a solution on other questions here. Any help will be appreciated. Thank you very much!
I dont use framework
You are using a library, though, $ === jQuery
in order to make my file cleaner I decide to put the data in a Json file
You can just define a constants.js file and load that before your other scripts.
For example,
constants.js
const messages = [
{ date: '2020-1-1', content:'message1'},
]
main.js
alert(messages);
index.html
<script src="constants.js"></script>
<script src="main.js"></script>
#Alvin Stefanus
Because x,z and messages were undefined and didnt let the code work, I also add
let messages,x,z = [];
And now it works perfectly with your solution.
I will use it as you told also for the other operations.
Thank you very much it helped for my problem and gave me a new technique.
EDIT:
I also tried to delete this part
var start = x;
$.getJSON('messages.json', function(data) {
messages = data;
}); <-- this
var end = z;
And it also works! That means that the problem was not the async function but because I didnt put the loop within the curly bracket of
$.getJSON('messages.json', function(data) {
//The data is finished being filled here
}
Ok this is probably the issue. $.getJSON() is an async function, the code will not wait until the closing curly bracket of the method:
var start = x;
$.getJSON('messages.json', function(data) {
messages = data;
}); <-- this
var end = z;
The code will run var end = z; before the $.getJSON() finished getting the result, because it is asynchronous function. In other word, when the code is currently at var end = z, $.getJSON() is still working to get the data, and has not been finished. That is why the messages = data is not being called yet.
So here is what you want to do:
$.getJSON('messages.json', function(data) {
messages = data;
for (const item of messages) {
if (item.date === todayDay) {
console.log(item.content);
var newPara = document.createElement("p");
var textNode = document.createTextNode(item.content);
newPara.appendChild(textNode);
var nodeParent = document.getElementById("titre");
var nodeChild = document.getElementById("child1");
nodeParent.appendChild(newPara, nodeChild);
}
}
});
Do all your needed operations within the curly bracket of
$.getJSON('messages.json', function(data) {
//The data is finished being filled here
}
This is a callback function. You can learn more about callback function here
Some Info
Yes the loop has to be inside the callback function to run after the data has been retrieved. To give you better understanding about the async function, you can also put your loop outside within a timeout function, but you will never want this, because you will not know how long the operation for retrieving the data will run.
For example:
$.getJSON('messages.json', function(data) {
messages = data;
});
setTimeout(function() {
for (const item of messages) {
if (item.date === todayDay) {
console.log(item.content);
var newPara = document.createElement("p");
var textNode = document.createTextNode(item.content);
newPara.appendChild(textNode);
var nodeParent = document.getElementById("titre");
var nodeChild = document.getElementById("child1");
nodeParent.appendChild(newPara, nodeChild);
}
}
}, 2000); //run after 2 seconds
Im sure the code above will also work, the process of getting the data should not be longer than 2 seconds.
Again this is not a correct way to do it, just to give you better understanding of async function.

Storing and retrieving data from Firebase comes back in different format

I'm trying to build this timetracker app where users can log how many hours per day they have worked. To give you an idea of what my app looks like, I put together a fiddle: https://jsfiddle.net/9vhfmjpy/
Here comes the tricky part. Whenever I try to store the data into a node in firebase by doing this:
submitHours() {
var uid = firebase.auth().currentUser.uid;
firebase
.database()
.ref("userhours/" + uid)
.set(this.rows)
.then(data => {
console.log(data);
});
},
it is turned into an object with an index value, as such:
userhours: {
userId: {
0: {
name: "username",
times: "time here"
}
}
}
Screenshot: https://prnt.sc/kpglr9
Having it formatted with that index makes it really to maintain. I can't effectively update/set/retrieve nodes.
I can use something like
loadUserHours() {
var userId = firebase.auth().currentUser.uid;
firebase.database().ref("userhours").once("value").then((data) => {
const allRows = [];
let obj = data.val();
for (let key in obj) {
allRows.push({
name: obj[key][0].name,
times: obj[key][0].times
})
}
console.log(allRows)
this.rows = allRows
})
},
to simply retrieve the values, but now... if there is more than 1 user in the userhours node I can't really update my node. If I try to use my submitHours() method now after updating the values for user #2 (https://prnt.sc/kpgqzq) it'll store the new information in a new node, in something that looks like this: https://prnt.sc/kpgqgs,
Can anyone help me out on how I can effectively store and retrieve data for my app?
Thanks a ton

javascript How to check the same data is available for the second time

I have a tricky requirement which im not able to fix.
I have a button and if i click on that button, Im getting below data from a REST web service ..
{
"results": [{
"Reqdate": "\/Date(1520899200000)\/",
"Tooltip": "13.03.2018 Blood Donation Approved ",
"Legendid": "GROUP_LEVEL1"
},{
"Reqdate": "\/Date(1523836800000)\/",
"Tooltip": "16.04.2018 Privilege Leave Sent ",
"Legendid": "BADVALUE_LIGHT",
},{
"Reqdate": "\/Date(1524528000000)\/",
"Tooltip": "24.04.2018 Privilege Leave Sent ",
"Legendid": "BADVALUE_LIGHT",
}]
}
If im getting the above data for the first time. Im going to display one section. Now again if i click on the same button, If i get the same data in the service then i have to hide the section. But im not able to check the same data for the second time.
Im trying to fix this issue by storing the data in a variable like below..
var firstTimeResults = data.results;
Now im not able to check if the same data is coming for the second time. Actually im not able to produce the sample code too. Im sorry for that
Can someone please help me to fix this issue.
I am not fully understand your problem but I think you can store your data as JSON and check if the same data is return from the second time onwards?
Code example
// Variable declaration
var firstTimeResults = null;
// When data return
var dataJson = JSON.stringify(data.results);
if (firstTimeResults === null) {
firstTimeResults = dataJson;
}
else {
// check to see if the data is the same as the firstTimeResults
var isSame = firstTimeResults === dataJson;
if (isSame) {
// Same
} else {
// Not the same
}
}
You can simply try with Lodash library.
It makes JavaScript easier to work with arrays, numbers, objects, strings, etc.
https://lodash.com/
var firstResult = null;
var secondResult;
var showSection;
function getData() {
// here goes your API request to get the data
};
function onButtonClick() {
this.getData().then(function(value) {
if !(firstResult) {
firstResult = value;
showSection = true;
return;
}
secondResult = value;
if (_.isEqual(firstResult, secondResult)) {
showSection = false;
}
})
};
Hope this will be helpful to you!

Using idb instead of localStorage

I'm following the Progressive Web App lab from Google and it says that it's using localStorage for simplicity but that we should change it to idb.
Basically, we want to store a list of cities to display their weather information.
I tried using plain idb following the info here but I think I'm too new to this and I couldn't get any of this. Am I supposed to do:
const dbPromise = idb.open('keyval-store', 1, upgradeDB => {
upgradeDB.createObjectStore('keyval');
});
and would keyval be the name of my variable where I would use keyval.get() or keyval.set() to get and store values?
I decided to move on to the simpler idbKeyval, I'm doing:
app.saveSelectedCities = function() {
var selectedCities = JSON.stringify(app.selectedCities);
idbKeyval.set(selectedCities);
};
instead of the localStorage example:
app.saveSelectedCities = function() {
var selectedCities = JSON.stringify(app.selectedCities);
localStorage.selectedCities = selectedCities;
};
and
app.selectedCities = idbKeyval.keys().then(keys => console.log(keys)).catch(err => console.log('It failed!', err));
instead of the localStorage example:
app.selectedCities = localStorage.selectedCities;
But my app is not loading any data, and in the developer tools console, I get:
app.js:314 Uncaught ReferenceError: idbKeyval is not defined(…)
I'm sure I'm missing something trivial but these are my first steps with javascript and the likes, so please, any help with any of the points touched here would be greatly appreciated!
Given the error you're seeing, it looks like you've forgotten to include the idb-keyval library.
I too was going through this, and wanted it to work with localForage. Took a bit, because I'm new to it too, but here is what I used for the save and load functions which made it all work.
// TODO add saveSelectedCities function here
// Save list of cities to localStorage
app.saveSelectedCities = function() {
var selectedCities = JSON.stringify(app.selectedCities);
localforage.setItem('selectedCities', selectedCities);
//localStorage.selectedCities = selectedCities;
}
localforage.getItem('selectedCities').then(function(cityList) {
app.selectedCities = cityList;
app.selectedCities.forEach(function(city) {
app.getForecast(city.key, city.label);
});
}).catch(function(err) {
app.updateForecastCard(initialWeatherForecast);
app.selectedCities = [
{key: initialWeatherForecast.key, label: initialWeatherForecast.label}
];
app.saveSelectedCities();
});

AngularJS and Restangular, trying to convert update method to API

I'm trying to convert my basic crud operations into an API that multiple components of my application can use.
I have successfully converted all methods, except the update one because it calls for each property on the object to be declared before the put request can be executed.
controller
$scope.update = function(testimonial, id) {
var data = {
name: testimonial.name,
message: testimonial.message
};
dataService.update(uri, data, $scope.id).then(function(response) {
console.log('Successfully updated!');
},
function(error) {
console.log('Error updating.');
});
}
dataService
dataService.update = function(uri, data, id) {
var rest = Restangular.one(uri, id);
angular.forEach(data, function(value, key) {
// needs to be in the format below
// rest.key = data.key
});
// needs to output something like this, depending on what the data is passed
// rest.name = data.name;
// rest.message = data.message;
return rest.put();
}
I tried to describe the problem in the codes comments, but to reiterate I cannot figure out how to generate something like rest.name = data.name; without specifying the name property because the update function shouldn't need to know the object properties.
Here is what the update method looked like before I started trying to make it usable by any of my components (this works)
Testimonial.update = function(testimonial, id) {
var rest = Restangular.one('testimonials', id);
rest.name = testimonial.name;
rest.message = testimonial.message;
return rest.put();
}
How can I recreate this without any specific properties parameters hard-coded in?
Also, my project has included lo-dash, if that helps, I don't know where to start with this problem. Thanks a ton for any advice!
Try like
angular.extend(rest,testimonial)
https://docs.angularjs.org/api/ng/function/angular.extend

Categories

Resources