How to use the Firebase real time database for web application - javascript

In my website I'm Showing my database after user has given the database name, Is there any way I can constantly update the web shown databasebase without refreshing the page . I've tried using setInterval but it's not working for some reason .
function c(){
setInterval(beta, 1000);
}
function beta(){
var d = document.getElementById("opopo").value;
var firebaseRefff= firebase.database().ref('LOCATION/'+d);
firebaseRefff.on('child_added', snap=> {
var slot=snap.getKey();
var alloted=snap.child("ALLOTED").val();
var date=snap.child("DATE").val();
var limit=snap.child("LIMIT").val();
var time=snap.child("TIME").val();
$("table tbody").append(""+slot+""+alloted+""+date+""+limit+""+time+"Null");
});
}

You do not need, and should not use, setInterval to trigger the queries. What you have in your beta() function looks pretty good.
firebaseRefff.on('child_added', snap => {}) means "whenever a child is added under this location, trigger the callback function (empty in my example) with the parameter 'snap'". It will also be called once, initially, for each child that is already at that database reference location.
You need to make sure you've called beta() once to setup this trigger.
If you're still having problems, you might want to insert logging to make sure beta() is being called, what the full reference path is, if the callback is ever triggered, and if your jquery string is correct.

Related

knockout: Trouble removing a newly added item

I'm trying to learn how to use KnockOut... never have before and I've been thrown into the fire on a site already using it. Everything here works fine:
function MasterViewModel() {
var self = this;
self.Supervisors = ko.mapping.fromJS(#Html.Raw(JsonConvert.SerializeObject(Model.Supervisors)));
self.AddSupervisor = function(request) {
var request = new Supervisor({
FullName: $('#SupervisorId option:selected').text(),
SupervisorId: $('#SupervisorId option:selected').val()
});
self.Supervisors.push(request);
// do server side call here
}
self.RemoveSupervisor = function(request) {
if (request.SupervisorID() > 0)
{
self.Supervisors.remove(request);
// do server side call here
}
}
}
Well. Everything almost works fine:
The initial data from the server loads and displays perfectly
I can remove existing items (that came from the server on the original page load)
I can add new items
But, when I try to remove an item that I just added, I get this:
Uncaught TypeError: request.SupervisorID is not a function
SupervisorId is a dropdown. The AddSupervisor call is made from a button. I can show the HTML if needed. Also, although I may not need this if:
if (request.SupervisorID() > 0)
Even without it, I am going to need the ID of the supervisor that was added.
I'm guessing the server side isn't case-sensitive, and is loading data with SupervisorID. When you add a new one, you're creating it with SupervisorId (lowercase d). The server must be accepting of that. JavaScript isn't.
You need to either change the newly created users to use SupervisorID, or have the RemoveSupervisor function use SupervisorId - whichever change makes more sense in your overall structure.

Run JQuery when data is loaded in Firebase

i have a problem that i need first to get the image links from the Firebase data base then i call a JQuery code that will organize the images in a beautiful way >> But it seems that the Jquery runs before i get the images,
Help Please ..!
JS Function
new Firebase("https://zoominp.firebaseio.com/photos/"+imageID)
.once('value', function(snap)
{
link = snap.child('imageLink').val();
link = 'images/'+link;
var id = "img";
div.innerHTML += "";
});
JQuery
jQuery("#gallery").unitegallery(
{
tiles_type:"nested",
tiles_nested_optimal_tile_width:200
});
Firebase loads (and synchronizes) the data asynchronously. So the jQuery code you have, will indeed execute before the data has come back from the server.
To fix this, move the jQuery code into the Firebase callback:
var ref = new Firebase("https://zoominp.firebaseio.com/photos/"+imageID);
ref.on('value', function(snap) {
link=snap.child('imageLink').val();
link='images/'+link;
var id="img";
div.innerHTML = div.innerHTML +"";
jQuery("#gallery").unitegallery({
tiles_type:"nested",
tiles_nested_optimal_tile_width:200
});
});
I also changed once() to on(). With that tiny change, your HTML will be updated whenever the data in the database changes. Try changing the data and you'll experience the "magic" of Firebase.
Since asynchronous loading is hard to wrap your head around when you first encounter it, I highly recommend that you read the more in-depth answers to these questions:
How do I return the response from an asynchronous call?
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
Handling Asynchronous Calls (Firebase) in functions
Returning value from a jQuery function
i have never worked with a Firebase, but you will need to have your actual resources ready before running the jQuery - you cannot do this in a synchronous way, as when you call your jquery unitedGallery it is called before the .once('value') event triggers.
do you call that new Firebase(.... thing more times in a loop or something? you could do something like keeping information about whether have all the images loaded in an array. something like this: let's assume, your images are stored in an array allOfYourImages. then,
define a global variable like this
var images_loaded=[];
for(var i=0; i<allOfYourImages.length; i++){ images_loaded[i]=false; }
then i assume you somehow iterate over your pictures since you are using imageID. add an incrementing variable var image_number=0; before the iterator and do image_number++ after each image iteration. like
var image_number=0;
...iteratorofyourchoiseihavenoideawhatareyouusing...{
new Firebase("https://zoominp.firebaseio.com/photos/"+imageID).once('value', function(snap){
...DOM stuff previously did ...
images_loaded[image_number]=true;
checkAllImagesLoaded();
});
image_number++;
}
notice the checkAllImagesLoaded() function. this will look whether have all your images already loaded and fire the jQuery gallery thing, like this
checkAllImagesLoaded(){
var all_loaded=true;
for(var i=0; i<allOfYourImages.length; i++){
all_loaded &= images_loaded[i]; //in case any of the items is false, it will set the all_loaded to false
}
if(all_loaded){
..your jQuery.("#gallery").unitegallery stuff..
}
}

Two-way data binding for a Meteor app

I've built an app that is form-based. I want to enable users to partially fill out a form, and then come back to it at a later date if they can't finish it at the present. I've used iron router to create a unique URL for each form instance, so they can come back to the link. My problem is that Meteor doesn't automatically save the values in the inputs, and the form comes up blank when it is revisited/refreshes. I tried the below solution to store the data in a temporary document in a separate Mongo collection called "NewScreen", and then reference that document every time the template is (re)rendered to auto fill the form. However, I keep getting an error that the element I'm trying to reference is "undefined". The weird thing is that sometimes it works, sometimes it doesn't. I've tried setting a recursive setTimeout function, but on the times it fails, that doesn't work either. Any insight would be greatly appreciated. Or, if I'm going about this all wrong, feel free to suggest a different approach:
Screens = new Meteor.Collection('screens') //where data will ultimately be stored
Forms = new Meteor.Collection('forms') //Meteor pulls form questions from here
NewScreen = new Meteor.Collection('newscreen') //temporary storage collection
Roles = new Meteor.Collection('roles'); //displays list of metadata about screens in a dashboard
//dynamic routing for unique instance of blank form
Router.route('/forms/:_id', {
name: 'BlankForm',
data: function(){
return NewScreen.findOne({_id: this.params._id});
}
});
//onRendered function to pull data from NewScreen collection (this is where I get the error)
Template.BlankForm.onRendered(function(){
var new_screen = NewScreen.findOne({_id: window.location.href.split('/')[window.location.href.split('/').length-1]})
function do_work(){
if(typeof new_screen === 'undefined'){
console.log('waiting...');
Meteor.setTimeout(do_work, 100);
}else{
$('input')[0].value = new_screen.first;
for(i=0;i<new_screen.answers.length;i++){
$('textarea')[i].value = new_screen.answers[i];
}
}
}
do_work();
});
//onChange event that updates the NewScreen document when user updates value of input in the form
'change [id="on-change"]': function(e, tmpl){
var screen_data = [];
var name = $('input')[0].value;
for(i=0; i<$('textarea').length;i++){
screen_data.push($('textarea')[i].value);
}
Session.set("updateNewScreen", this._id);
NewScreen.update(
Session.get("updateNewScreen"),
{$set:
{
answers: screen_data,
first: name
}
});
console.log(screen_data);
}
If you get undefined that could mean findOne() did not find the newscreen with the Id that was passed in from the url. To investigate this, add an extra line like console.log(window.location.href.split('/')[window.location.href.split('/').length-1], JSON.stringify(new_screen));
This will give you both the Id from the url and the new_screen that was found.
I would recommend using Router.current().location.get().path instead of window.location.href since you use IR.
And if you're looking for two way binding in the client, have a look at Viewmodel for Meteor.

Chrome Extension Notifications Not Always Created - Reuse?

Let's say I want to show the same notification each time something happens. That's what I currently use:
chrome.notifications.create(id, {
type:"basic",
title:"Title",
message:"My message",
iconUrl: "icon.png",
}, notificationResult);
But sometimes the notification doesn't appear.
Is that an id thing ? Do I need to reuse an already created notification ? Can I not create a new notification with the same id ?
I tried to do a var notification = chrome.notifications.create(id .... ) and do a notification.show() in case I already created one with the same id but that also didn't solve it.
So - do I need to recreate an existing notification each time I want to show the same one (which currently doesn't work for me), or is there a different way? How to make sure it pops every time?
The id in the create function is specifically for reusing. IDs must be unique. If you use create with an ID of an existing notification, it basically behaves like an update.
If a notification exists, it may no longer be shown but only be visible in the Message Center. In this case, the notification IS updated - but not shown again.
The API docs specify that you can pass an empty string to the notification to get a unique new id. If you need it, it is passed to the callback.
But if you do want to reuse the ID (ensuring that the notification is unique), you can use priority trick to make it show again.
You can clear the notification if its not use and if you want to use the same id.
For example :
function Notify(){
var my_notif_id="some_id";
//This will clear your previous notifcation with the same ID
chrome.notifications.clear(my_notif_id,function(){});
chrome.notifications.create(my_notif_id,options,function(){});
}
Now each time you call the notify function to display notification it will clear the old notification before displaying new notification and gets displayed.
UPDATED
As #Xan suggested, Its good to incorporate the create() method inside callback function of clear()
So here is the complete example :
function Notify(id, options){
//This will clear your previous notifcation with the same ID
chrome.notifications.clear(id, function() {
//inside callback function
chrome.notifications.create(id, options, function(){});
});
}

Variable not updating in script string, yet it updates

Very confused here.
I have a search box which reads a list of school names from my database. When I select a school, the id (from the db) gets put in a hidden textbox.
I also have a search box which reads a list of courses from my database. However, I made the query so that it only reads the courses from the selected school.
It does that, in theory.
I was planning to pass the school id, which I grab from the hidden box, to the search script which in turn passes it to my database query. However, the variable I put my school id in doesn't seem to be updating.. yet it does. Let me explain.
I come on the page. The school for my test account has id 1. The id number in my hidden box is indeed 1. I search for a school which I know has some courses assigned to it: the id number in the box changes to 3.
I have a JS variable called school_id which I declared outside of my $(document).ready. I assume that means it's global (that's what I got taught even though SO told me once it isn't really the correct way to do this. Still have to look into that). I wrote a function which updates this variable when the school search box loses focus:
$("#school").blur(function() {
school_id = $("#school_id").val();
});
A quick javascript:alert(school_id); in my browser bar also shows the updated variable: it is now 3 instead of 1.
Onto the search script part of my page (excerpt of the script):
script:"/profiel/search_richting?json=true&limit=6&id=" + school_id + "&"
As you can see, I pass the school_id variable to the script here. However, what seems to be happening is that it always passes '1', the default variable when the page loads. It simply ignores the updated variable. Does this string get parsed when the page loads? In other words, as soon as the page loads, does it actually say &id=1? That's the only idea I can come up with why it would always pass '1'.
Is there a way to make this variable update in my script string? Or what would be the best way to solve this? I'm probably missing out on something very simple here again, as usual. Thanks a lot.
EDIT
Updated per request. I added a function getTheString as was suggest and I use the value of this function to get the URL. Still doesn't work though, it still seems to be concatenating before I get a chance to update the var. HOWEVER, with this code, my ajax log says id:[object HTMLInputElement], instead of id:1. Not sure what that means.
<script type="text/javascript">
var school_id;
$(document).ready(function() {
$("#school").blur(function() {
school_id = $("#school_id").val();
});
// zoekfunctie
var scholen = {
script:"/profiel/search_school?json=true&limit=6&",
varname:"input",
json:true,
shownoresults:false,
maxresults:6,
callback: function (obj) { document.getElementById('school_id').value = obj.id; }
};
var as_json = new bsn.AutoSuggest('school', scholen);
var richtingen = {
script: getTheString(),
varname:"input",
json:true,
shownoresults:true,
maxresults:6
};
var as_json2 = new bsn.AutoSuggest('studierichting', richtingen);
});
function getTheString() {
return "/profiel/search_richting?json=true&limit=6&id=" + school_id + "&";
}
</script>
This is because the URL is static, it is not updated as the ID changes.
You should update the URL as part of the code you wrote to get the ID:
$("#school").blur(function() {
school_id = $("#school_id").val();
// update URL here ...
});
Aren't you concatenating script:"/profiel/search_richting?json=true&limit=6&id=" + school_id + "&" before the event is fired and the var updated?
Okay. So the problem was my third party plug-in instead of the code I wrote. I fixed this by editing the code of the autoSuggest plugin so it now includes my id field in the AJAX request.
var url = this.oP.script+this.oP.varname+"="+encodeURIComponent(this.sInp)+"&id="+ $("#school_id").val();
Thanks to everyone who tried to help me out!

Categories