Vue JS : Wait firebase to load - javascript

I want to use firebase inside a Vue JS component, but it seems like the firebase object is loaded after the creation of my component.
Is there a way to wait for firebase to load before executing JS code ?
Exemple : i want to create a vue composant called loader which output the firebase object on the webconsole at his creation
<html>
<head>
<!-- Firebase -->
<script defer src="/__/firebase/5.0.4/firebase-app.js"></script>
<!-- include only the Firebase features as you need -->
<script defer src="/__/firebase/5.0.4/firebase-auth.js"></script>
<script defer src="/__/firebase/5.0.4/firebase-database.js"></script>
<script defer src="/__/firebase/5.0.4/firebase-messaging.js"></script>
<script defer src="/__/firebase/5.0.4/firebase-storage.js"></script>
<!-- initialize the SDK after all desired features are loaded -->
<script defer src="/__/firebase/init.js"></script>
<!-- Vue.js-->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
</head>
<body>
<div id="app"></div>
<script>
var loader = {
template: '<div></div>',
created: function(){
console.log(window.firebase); // undefined
}
};
var app = new Vue({
el : '#app',
template :
`<div>
<loader></loader>
</div>`,
components : {
'loader' : loader
}
});
</script>
</body>
</html>
It doesn't work but, of course, one second later i can output the firebase object on the console.
PS :
It is my first question on this website so if you have any advice on how to ask question, i will take it as well.
I am french so pardon my english

You need to remove the defer attributes from the firebase scripts. It will cause the scripts to be executed once the whole document has been parsed, which means that your script in the body runs before firebase scripts.

Related

Firebase signInWithPopup() giving typeError while signInWithRedirect() is working

i am using the following simple code, which worked for some days and is now not working -
function signIn() {
// Sign into Firebase using popup auth & Google as the identity provider.
var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider);
}
document.getElementById("signin").onclick = signIn;
it is giving error -
Uncaught TypeError: e.open is not a function
at Mt (firebase-auth.js:sourcemap:1)
at ii (firebase-auth.js:sourcemap:1)
at zh.t.Xc (firebase-auth.js:sourcemap:1)
at zh.i [as signInWithPopup] (firebase-auth.js:sourcemap:1)
at HTMLButtonElement.signIn (sign-in.js:4)
also when i change the signInWithPopup with signInWithRedirect, it is working. I don't know where the problem is?
I am using following links in head of index.html -
<script src="https://apis.google.com/js/api:client.js"></script>
<!-- update the version number as needed -->
<script defer src="/__/firebase/8.6.2/firebase-app.js"></script>
<!-- include only the Firebase features as you need -->
<script defer src="/__/firebase/8.6.2/firebase-auth.js"></script>
<script defer src="/__/firebase/8.6.2/firebase-database.js"></script>
<script defer src="/__/firebase/8.6.2/firebase-firestore.js"></script>
<script defer src="/__/firebase/8.6.2/firebase-functions.js"></script>
<script defer src="/__/firebase/8.6.2/firebase-messaging.js"></script>
<script defer src="/__/firebase/8.6.2/firebase-storage.js"></script>
<script defer src="/__/firebase/8.6.2/firebase-analytics.js"></script>
<script defer src="/__/firebase/8.6.2/firebase-remote-config.js"></script>
<script defer src="/__/firebase/8.6.2/firebase-performance.js"></script>
<!--
initialize the SDK after all desired features are loaded, set useEmulator to false
to avoid connecting the SDK to running emulators.
-->
<script defer src="/__/firebase/init.js?useEmulator=true"></script>

JQuery library not available in another script when loaded first

I have a single HTML page with various JS imports.
I'm importing JQuery, then a custom script of my own, which I'd like to use the JQuery library in, though I get a '$ is not defined' exception.
I thought as I'm loading up JQuery first, I should be able to reference it in my external script?
Is this something RequireJS would solve?
baseTemplate.html
<body>
<template id="navbar"></template>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<script src="navbarTemplate.js"></script>
</body>
navbarTemplate.js
function isTemplateElementSupported() {
return 'content' in document.createElement('template');
}
if (isTemplateElementSupported()) {
$('#navbar').append("<table><tr><td><b>some test</b></td></tr></table>");
} else {
alert('Please update browser!');
}
Try to use "defer" option for correct load sequence of your javascripts.
<body>
<template id="navbar"></template>
<script defer src="https://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<script defer src="navbarTemplate.js"></script>
</body>

How to create Backbone View in a separate js file

I'm trying to understand how to modularize the Backbone ToDo tutorial
Originally everything is inside the same file, but if I try to extract to another file:
var TodoView = Backbone.View.extend({
...
});
then this throws an error:
var view = new TodoView({model: todo});
**Uncaught TypeError: undefined is not a function**
It's probably due to a scope issue, but I don't know how to create a reference inside the $(function() so I can create this new object inside the main function.
Assuming that your first code part is TodoView.js,
and your second code part is app.js.
Write your html file like this,
<html>
<head>
<script type="text/javascript" src="js/TodoView.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</head>
<body>
// your dom
</body>
</html>
(Edited, at 2015-07-27)
sorry for my late reply.
how about this?
<html>
<head></head>
<body>
<!-- your dom -->
<script type="text/javascript" src="js/TodoView.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</body>
</html>
In many case, most javascript codes are appended to just before </body>, so that javascript can use your dom!
You can use something like require.js to load your external files and manage dependancies.
Ok, the solution was to move the script references to the end of the body instead of inside the head tags.
I think that the reason is that TodoView.js is making use of templates that were defined in the body, and since the js file was being loaded before the body, the templates were not yet available.

Meteor - Ckeditor Integration

I'm not sure if there has been a change in the way Meteor loads items, or the way it handles jquery, but I'm having an awful lot of trouble getting ckeditor to come up.
Main Template (Iron-router):
<template name="layout">
<head>
<script type="text/javascript" src="js/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="js/ckeditor/adapters/jquery.js"></script>
</head>
.....
</template>
Independent Editor Template:
<template name="editor">
<div class="editor_container">
<textarea class="editor"></textarea>
</div>
</template>
Ckeditor located at public/js/ckeditor, any time I try to do the Template.editor.rendered() technique, or even just trying to type $('.editor').ckeditor(); into the console, I get an error of:
$('.editor').ckeditor();
VM48825:2 Uncaught TypeError: undefined is not a function
Any ideas?
Try taking the <head> section out of the layout template. Reading here I believe the <head> section is treated specially be meteor (see: http://docs.meteor.com/#/full/structuringyourapp) and that it being inside a template may be causing the JS to actually not be loaded. Just a guess though.
<head>
<script type="text/javascript" src="js/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="js/ckeditor/adapters/jquery.js"></script>
</head>
<template name="layout">
.....
</template>
You can use IRLibLoader from iron:router into the onBeforeAction like this.
Router.route('/editor', {
name: 'editor',
template: 'layout',
onBeforeAction: function () {
var ckEditor = IRLibLoader.load('/js/ckeditor/ckeditor.js');
var adapter = IRLibLoader.load('/js/ckeditor/adapters/jquery.js');
if(ckEditor.ready() && adapter.ready()){
console.log('The 2 JS just finish load');
this.next(); // Render the editor page
if(Meteor.isClient){
Template.editor.rendered = function(){
$('.editor').ckeditor();
console.log("loading coeditor when template fully rendered");
}
}
}
}
});
Alternative on the main layout you can use this.
<head>
<script type="text/javascript" src="js/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="js/ckeditor/adapters/jquery.js"></script>
</head>
<template name="layout">
{{> yield}}
</template>
<template name="editor">
<div class="editor_container">
<textarea class="editor"></textarea>
</div>
</template>
And do the same rendered function
Template.editor.rendered = function(){
$('.editor').ckeditor();
//or make a little delay (1sec)
Meteor.setTiemout(function(){
$('.editor').ckeditor();
},100)
}
There are several problems with your code :
You can't put <head> sections inside another template, it must be done outside all templates.
The path to your JS files are broken, you must prepend a slash to them to reference files in the public directory.
Loading scripts in <head> sections is not a good idea because they will be loaded when your app first loads for every user, even if they never use the editor.
Here is a solution where we load every scripts asynchronously using jQuery promises when the editor template is rendered, and only then initialize the CKEditor.
Template.editor.rendered=function(){
var template=this;
$.when(
$.getScript("/js/ckeditor/ckeditor.js"),
$.getScript("/js/ckeditor/adapters/jquery.js")
).done(function(){
template.$(".editor").ckeditor();
});
};

What is the cause for "angular is not defined"

I'm following the video tutorials on egghead.io but while trying to follow his example when he created a factory (see video here) I keep getting "angular is not defined" Reference Error but I have included the angular script
This is my html page:
<!DOCTYPE html>
<html>
<head>
<title>Prototype</title>
<link rel="stylesheet" type="text/css" href="foundation.min.css">
<script type="text/javascript" src="main.js"></script>
</head>
<body>
<div data-ng-app="">
<div data-ng-controller="FirstController">
<input type="text" data-ng-model="data.message">
<h1>{{ data.message }}</h1>
</div>
<div data-ng-controller="SecondController">
<input type="text" data-ng-model="data.message">
<h1>{{ data.message }}</h1>
</div>
</div>
<script type="text/javascript" src="angular.min.js"></script>
</body>
</html>
and this is my javascript file "main.js":
//Services
// step 1 create an app
var myApp = angular.module('Data', []).
// tep 2 create factory
// Service name, function
myApp.factory('Data', function(){
return { message: "I'm Data from a Service" }
});
//Controllers
function FirstController($scope, Data){
$scope.data = Data;
}
function SecondController($scope){
}
I have read a few posts where similar happen (here) and please correct me if I'm wrong but I think it is to do with Boot strapping andI have tried manually bootstrapping using angular.bootstrap(document, ['Data']); but with no success, still get same error.
But What I want to know is, Why this works for so many examples online, like the egghead video series, but I have issues as I believe I have followed his video very closely. is it a change in angular in recent versions?
You have to put your script tag after the one that references Angular. Move it out of the head:
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="main.js"></script>
The way you've set it up now, your script runs before Angular is loaded on the page.
You have not placed the script tags for angular js
you can do so by using cdn or downloading the angularjs for your project and then referencing it
after this you have to add your own java script in your case main.js
that should do
I had the same problem as deke. I forgot to include the most important script: angular.js :)
<script type="text/javascript" src="bower_components/angular/angular.min.js"></script>

Categories

Resources