Description
My goal is to use the polymerfire element to send a request to a Firebase endpoint to detect if there is data there and, if so, its content.
Please include in your answer a working demo if possible and extra points if you point to some good documentation as the current documentation is insufficient.
Expected outcome
I expect the demo page to look like:
CLICK ME
ornithischia
foo bar baz
And when the CLICK ME button is pressed, the following to appear in the console:
"You clicked me!"
"triceratops"
"{appeared: -68000000, height: 3, length: 8, order: "ornithischia", vanished: -66000000, weight: 11000}"
Actual outcome
The the demo page looks like:
CLICK ME
foo bar baz
And when the CLICK ME button is pressed, the following actually appears in the console:
"You clicked me!"
"triceratops"
"{}"
Live Demo
http://jsbin.com/fasovaxonu/1/edit?html,console,output
<!doctype html>
<head>
<meta charset="utf-8">
<!-- Source: https://github.com/Download/polymer-cdn -->
<base href="https://cdn.rawgit.com/download/polymer-cdn/1.7.0.2/lib/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymerfire/polymerfire.html">
<link rel="import" href="paper-button/paper-button.html">
</head>
<body>
<dom-module id="x-element">
<template>
<style></style>
<firebase-app name="my-app"
auth-domain="dinosaur-facts.firebaseapp.com"
database-url="https://dinosaur-facts.firebaseio.com/"
>
</firebase-app>
<p>
<paper-button on-tap="_onTap">Click Me</paper-button>
</p>
<!---->
<firebase-query
app-name="my-app"
path="https://dinosaur-facts.firebaseio.com/dinosaurs"
data="{{dinosaurs}}"
>
</firebase-query>
<firebase-document
app-name="my-app"
path="https://dinosaur-facts.firebaseio.com/dinosaurs/triceratops"
data="{{triceratops}}"
>
</firebase-document>
[[triceratops.order]]
<br /><br />
<template is="dom-repeat" items="[[dinosaurs]]">
[[item.order]]
</template>
<template is="dom-repeat" items="[[test]]">
[[item]]
</template>
<!---->
</template>
<script>
(function(){
Polymer({
is: "x-element",
properties: {
dinosaurs: Array,
test: {
value: function() {
return ['foo', 'bar', 'baz'];
}
},
},
_onTap: function() {
console.log('You clicked me!');
console.log('triceratops', JSON.stringify(this.triceratops));
}
});
})();
</script>
</dom-module>
<x-element></x-element>
</body>
You first need to include <firebase-app> to initialize firebase.
<firebase-app
database-url="dinos-89701.firebaseio.com"
api-key="AIzaSyDLkCy3RNC5uFomEjVsLUehpzKFDrfAplU"
auth-domain="dinos-89701.firebaseio.com">
</firebase-app>
Get your api-key here:
https://console.firebase.google.com/project/YOUR_PROJECT/settings/general/
Demo:
http://jsbin.com/joxatuz/1/edit?html,console,output
Related
I want to use the polymerfire element to fetch the data at https://dinosaur-facts.firebaseio.com/dinosaurs and display the data in a dom-repeat element.
What am I doing wrong? How do I do that correctly?
Here is the jsBin.
http://jsbin.com/zeyimotasa/1/edit?html,console,output
<!doctype html>
<head>
<meta charset="utf-8">
<!-- Source: https://github.com/Download/polymer-cdn -->
<base href="https://cdn.rawgit.com/download/polymer-cdn/1.7.0.2/lib/">
<!--- ->
<base href="https://polygit.org/components/">
<!--- ->
Toggle below/above as backup when server is down
<!--- ->
<base href="https://polygit2.appspot.com/components/">
<!---->
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link href="polymer/polymer.html" rel="import">
<link href="polymerfire/polymerfire.html" rel="import">
<link href="paper-button/paper-button.html" rel="import">
</head>
<body>
<dom-module id="x-element">
<template>
<style></style>
<p>
<paper-button on-tap="_handleClick">Click Me</paper-button>
</p>
<!---->
<firebase-document
path="https://dinosaur-facts.firebaseio.com/dinosaurs"
data="{{dinosaurs}}"
>
</firebase-document>
<template is="dom-repeat" items="[[dinosaurs]]">
[[item.order]]
</template>
<template is="dom-repeat" items="[[test]]">
[[item]]
</template>
<!---->
</template>
<script>
(function(){
Polymer({
is: "x-element",
properties: {
dinosaurs: Array,
test: {
value: function() {
return ['foo', 'bar', 'baz'];
}
},
},
_handleClick: function() {
console.log('You clicked me!');
}
});
})();
</script>
</dom-module>
<x-element></x-element>
</body>
To get data in array/collection form, you need to use the <firebase-query> element, not <firebase-document>. You also need to initialize your application with <firebase-app>:
<firebase-app api-key="XXX" database-url="yyy" auth-domain="zzz"></firebase-app>
<firebase-query path="/dinosaurs" data="{{dinosaurs}}"></firebase-query>
<template is="dom-repeat" items="[[dinosaurs]]">
<!-- ... -->
</template>
You need a <firebase-app> to initialize the Firebase App, don't you?
In the index.html I use:
<template is="dom-bind" id="app">
In a normal dom-module I use:
<script>
(function() {
'use strict';
Polymer({
is: 'my-xxxx',
properties: {
/* location for properties */
}
Where do I define the properties used in the template dom-bind (f.i to have an observer attached to them?
Based on Polymer docs, you'd use JavaScript (inline or imported in index.html) to add template properties inside of an event handler for the template's dom-change event. For example, you could add a message property to the template with this script:
var t = document.getElementById('app');
t.addEventListener('dom-change', function() {
t.message = 'Hello world!';
});
See demo below:
<head>
<base href="https://polygit.org/polymer+:master/components/">
<script src="webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="polymer/polymer.html">
</head>
<body>
<template is="dom-bind" id="app">
{{message}}
</template>
<script>
var t = document.getElementById('app');
// The dom-change event signifies when the template has stamped its DOM.
t.addEventListener('dom-change', function() {
// auto-binding template is ready.
t.message = 'Hello world!';
});
</script>
</body>
jsbin
I have an array of objects which has a field to indicate whether its properties should be displayed:
[{
state: true
},
{
state: false
},
{
state: false
}]
And I use Polymer iron-collapse's "opened" field to bind with state in order to collapse it.
This works in Polymer 0.5, but it fails in 1.0. Also, it works if I directly pass a boolean property - just not with an object.
When I say "doesn't work", I mean that the collapsing doesn't happen.
What did I fail to migrate properly? Or is this a bug in iron-collapse?
This Works:
(Using an Array of Boolean)
demo.html:
<html>
<head>
<link rel="import" href="iron-collapse-demo.html">
</head>
<body>
<iron-collapse-demo states='[ true, false, false ]'></iron-collapse-demo>
</body>
</html>
iron-collapse-demo.html:
<html>
<head>
<script src="../bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../bower_components/iron-collapse/iron-collapse.html">
</head>
<body>
<dom-module id="iron-collapse-demo">
<style>
</style>
<template>
<template is="dom-repeat" items="{{states}}">
<span on-tap="collapseToggle"><+></span>
<iron-collapse opened="{{item}}">
<div>Hello collapse!</div>
</iron-collapse>
</template>
</template>
</dom-module>
</body>
<script src="iron-collapse-demo.html.0.js"></script>
</html>
iron-collapse-demo.html.0.js:
Polymer({
'is': 'iron-collapse-demo',
'properties': {
'states': Array
},
'ready': function() {
},
'collapseToggle': function(event, detail, sender) {
event.model.item = !event.model.item;
},
});
This doesn't work:
(Using an Array of Object with a Boolean property)
demo.html
<html>
<head>
<link rel="import" href="iron-collapse-demo.html">
</head>
<body>
<iron-collapse-demo nums='[ {"state": true}, {"state": false}, {"state": false} ]'></iron-collapse-demo>
</body>
</html>
iron-collapse-demo.html:
<html>
<head>
<script src="../bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="../bower_components/iron-collapse/iron-collapse.html">
</head>
<body>
<dom-module id="iron-collapse-demo">
<style>
</style>
<template>
<template is="dom-repeat" items="{{nums}}">
<span on-tap="collapseToggle"><+></span>
<iron-collapse opened="{{item.state}}">
<div>Hello collapse!</div>
</iron-collapse>
</template>
</template>
</dom-module>
</body>
<script src="iron-collapse-demo.html.0.js"></script>
</html>
iron-collapse-demo.html.0.js:
Polymer({
'is': 'iron-collapse-demo',
'properties': {
'nums': Array
},
'ready': function() {
},
'collapseToggle': function(event, detail, sender) {
var num = event.model.item;
num.state = !num.state;
},
});
I found a hack/workaround, though I'm not convinced this should be the only way that works..
I wrapped the span and iron-collapse inside a div so that I can use a querySelector and toggle() the collapse.
iron-collapse-demo.html:
<template is="dom-repeat" items="{{nums}}">
<div>
<span on-tap="collapseToggle"><+></span>
<iron-collapse opened="{{item.state}}">
<div>Hello collapse!</div>
</iron-collapse>
</div>
</template>
iron-collapse-demo.html.0.js:
new collapseToggle:
'collapseToggle': function(event, detail, sender) {
// event.model.item.state = !event.model.item.state;
event.currentTarget.parentElement.querySelector('iron-collapse').toggle();
}
Try:
<iron-collapse horizontal opened$="[[item.state]]">
...
</iron-collapse>
HTML booleans are true when the attribute is present, not if the value of the attribute is true. Binding the attribute instead of value means Polymer outputs the attribute name when true but nothing for false.
Upon submission of a form, I want to push that data to my Firebase db and so I'm creating a function to do so (addMeeting). However, upon pressing the button to submit I get the error:
TypeError: undefined is not a function
at l.$scope.addMeeting (http://localhost:8000/js/controllers/meetings.js:10:12)
meetings.js:10:12 is right where my $push is if you'll look at my code below.
My HTML:
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>Angular Data</title>
<meta name="viewport" content="width=device-width, userscalable=no">
<link rel="stylesheet" href="css/style.css">
<!-- AngularJS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="js/lib/angular/angular-route.min.js"></script>
<script src="js/lib/angular/angular-animate.min.js"></script>
<!-- Firebase -->
<script src="https://cdn.firebase.com/js/client/2.2.2/firebase.js"></script>
<!-- AngularFire -->
<script src="https://cdn.firebase.com/libs/angularfire/1.0.0/angularfire.min.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers/registration.js"></script>
<script src="js/controllers/meetings.js"></script>
</head>
<body>
<header>
<nav class="cf" ng-include="'views/nav.html'"></nav>
</header>
<div class="page">
<main class="cf" ng-view></main>
</div>
</body>
</html>
My apps.js:
var myApp = angular.module('myApp',
['ngRoute', 'firebase', 'appControllers']);
var appControllers = angular.module('appControllers', ['firebase']);
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/login', {
controller: 'RegistrationController',
templateUrl: 'views/login.html'
}).
when('/register', {
controller: 'RegistrationController',
templateUrl: 'views/register.html'
}).
when('/meetings', {
controller: 'MeetingsController',
templateUrl: 'views/meetings.html'
}).
otherwise({
redirectTo: '/login'
});
}])
meetings.js -the Controller containing the addMeeting function that is failing:
myApp.controller('MeetingsController',
function($scope, $firebaseObject) {
var ref = new Firebase('https://angulardataldc.firebaseio.com/meetings');
var meetings = $firebaseObject(ref);
$scope.meetings = meetings;
$scope.addMeeting = function() {
meetings.$push({
name: $scope.meetingname,
date: Firebase.ServerValue.TIMESTAMP
})
}
}); //MeetingsController
The view that is calling that function upon submission of a form:
<section class="meetings cf">
<h1>Add Meetings</h1>
<form class="formgroup addmeeting cf"
name="myform"
ng-submit="addMeeting()"
novalidate>
<div class="inputwrapper">
<input type="text" name="meetingname" placeholder="Meeting Name"
ng-model="meetingname" ng-required="true">
</div>
<button type="submit" class="btn"
ng-disabled="myform.$invalid">+</button>
</form>
<h2>Your Meetings</h2>
<div class="meeting" ng-repeat="meeting in meetings">
<p>{{meeting.name}}</p>
</div>
</section>
**Edit: ** It has something to do with the .push() method itself. I see that in the latest version of angularfire/firebase it should be .push, instead of .$push, ad have changed that but it does not solve my problem. I reverted AngularFire and Firebase to versions 0.8.2 and 1.0.21 respectively, re-introduced the .asObject() and $push, and everything works fine. I don't understand why .push() is failing with all the latest (Firebase 2.2.2, AngularFire 1.0).
Firebase's AngularFire library has two primary types: $firebaseObject and $firebaseArray (instantiated through $asObject and $asArray respectively in pre-1.0 versions of AngularFire).
You're using both the wrong type and the wrong method. To quote AngularFire's documentation on its array type:
Synchronized arrays should be used for any list of objects that will be sorted, iterated, and which have unique IDs. The synchronized array assumes that items are added using $add(), and that they will therefore be keyed using Firebase push IDs.
So:
var ref = new Firebase('https://angulardataldc.firebaseio.com/meetings');
var meetings = $firebaseArray(ref);
$scope.meetings = meetings;
$scope.addMeeting = function() {
meetings.$add({
name: $scope.meetingname,
date: Firebase.ServerValue.TIMESTAMP
})
}
You made a typo, it should be .push instead of $push
CODE
$scope.addMeeting = function() {
meetings.push({
name: $scope.meetingname,
date: Firebase.ServerValue.TIMESTAMP
})
}
Reference
I am trying to use a dojo datagrid in a dojo dialog and I get the following dojo/parse error when trying to load the page.
dojo/parser::parse() error (new TypeError("d(...) is undefined", "http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojox//grid/DataGrid.js", 16))
If I comment out the require DataGrid statement, the parse error goes away. Notice I am not even trying to create a data grid yet. Just trying to build a bare bones page.
The following is the code for the page.
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Dojo Dialog with DataGrid</title>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.8.3/dijit/themes/claro/claro.css" media="screen">
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojox/grid/resources/Grid.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojox/grid/resources/claroGrid.css" />
<!-- load dojo and provide config via data attribute -->
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.8.3/dojo/dojo.js" data-dojo-config="isDebug: true, async: true, parseOnLoad: true"></script>
<script>
require(["dojo/parser", "dijit/Dialog", "dijit/form/Button"]);
require([
"dojox/grid/DataGrid",
"dojox/grid/cells",
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojo/_base/array",
"dojo/_base/lang",
"dojox/grid/_CheckBoxSelector",
"dojo/domReady!",
]);
//var grid2x;
</script>
</head>
<body class="claro">
<div data-dojo-type="dijit/Dialog" data-dojo-id="myFormDialog" title="Form Dialog"
execute="alert('submitted w/args:\n' + dojo.toJson(arguments[0], true));">
<div class="dijitDialogPaneContentArea">
</div>
<div class="dijitDialogPaneActionBar">
<button data-dojo-type="dijit/form/Button" type="submit" onClick="return myFormDialog.isValid();">
OK
</button>
<button data-dojo-type="dijit/form/Button" type="button" onClick="myFormDialog.hide()">
Cancel
</button>
</div>
</div>
<p>When pressing this button the dialog will popup:</p>
<button id="buttonThree" data-dojo-type="dijit/form/Button" type="button" onClick="myFormDialog.show();">
Show me!
</button>
</body>
</html>
Even though this post is old, your problem seems to be the comma after "dojo/domReady!," There should be no comma after the last import. Also load all that you want to load in the first require i.e instead of having <script>
require(["dojo/parser", "dijit/Dialog", "dijit/form/Button"]);
require([
"dojox/grid/DataGrid",
"dojox/grid/cells",
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojo/_base/array",
"dojo/_base/lang",
"dojox/grid/_CheckBoxSelector",
"dojo/domReady!",
]);
//var grid2x;
</script>
Just put all in one require as follows:
<script>
require(["dojo/parser",
"dijit/Dialog",
"dijit/form/Button",
"dojox/grid/DataGrid",
"dojox/grid/cells",
"dojo/store/Memory",
"dojo/data/ObjectStore",
"dojo/_base/array",
"dojo/_base/lang",
"dojox/grid/_CheckBoxSelector",
"dojo/domReady!"]);
//var grid2x;
</script>
problem is <html lang="en">. parser can't parse html components if lang="en". Remove it or override with data-dojo-config="lang='en-us'"