I have the following polymer element (with many lines of import for paper elements and firebase-auth removed) that I'd like to test using Web Component Tester.
<dom-module id="my-login">
<template>
<firebase-auth id="auth" app-name="myapp" provider="email"></firebase-auth>
<paper-input id="email" label="Enter Email"></paper-input>
<paper-input id="password" label="Enter password" type="password"></paper-input>
<paper-button id="signin" on-tap="_signIn" raised primary>Login</paper-button>
<paper-button id="signup" on-tap="_register" secondary>Register</paper-button>
</template>
<script>
Polymer({
is: 'my-login',
ready: function () {
this.$.email.value = "xxxxxxxxxxxxxxx";
this.$.password.value = "zzzzzzzzzzz";
},
_signIn: function () {
const email = this.$.email.value;
const passw = this.$.password.value;
const sgn = this.$.auth;
sgn.signInWithEmailAndPassword(email, passw) // *** ERRROR HERE ***
.then(response => {
});
}
});
</script>
</dom-module>
using the following test suite (lots of irrelevant details removed):
<!doctype html>
<html lang="en">
<head>
<script src="../bower_components/webcomponentsjs/webcomponents-lite.js></script>
<script src="../bower_components/web-component-tester/browser.js"></script>
<link rel="import" href="../src/my-login.html">
</head>
<body>
<test-fixture id="login">
<template>
<my-login></my-login>
</template>
</test-fixture>
<script>
suite('LOGIN', function () {
var el, loginBtn;
setup(function () {
el = fixture("login");
loginBtn = el.$$('#signin');
});
test('user login', done => {
loginBtn.click();
flush(_ => {
done();
});
});
});
</script>
</body>
</html>
but the test failed with the following error:
Error: Cannot read property 'signInWithEmailAndPassword' of undefined
HTMLElement.signInWithEmailAndPassword at /bower_components/polymerfire/firebase-auth.html:211
HTMLElement._signIn at /src/my-login.html:20
I noticed that the error says
Cannot read property signInWithEmailAndPassword of undefined
instead of
Cannot read property signInWithEmailAndPassword of null
The code snippet shows no <link rel="import" ...> but in my code I do have those lines included and other test cases for <paper-input> and <paper-button> are passing.
What did I do wrong?
I'm not sure if the following is the answer to my own question, but
after adding a stub that returns a Promise, the error disappeared and the above test is passing. However, I still did not figure out the cause of the undefined error above.
stub('firebase-auth', {
signInWithEmailAndPassword: function (e, p) {
return new Promise( (resolve, reject) => {
resolve("Yes");
});
}
});
Related
(Warning: requirejs newbie) I'm trying to set my baseUrl for require.config but I'm getting an error on a very very simple setup. I've tried many different combos with slashes but no luck.
index.html
<!DOCTYPE html>
<html>
<head>
<title>Requirejs way</title>
<meta charset="utf-8" />
</head>
<body>
<h1><span id="foo">Hello World</span></h1>
<input id="Button1" type="button" value="button" />
<script data-main="common" src="Scripts/require.js"></script>
<script type="text/javascript">
require(['common'], function () {
//Load up this page's script, once the 'common' script has loaded
require(['home']);
});
</script>
</body>
</html>
common.js
/*
The first JS file to be loaded. Takes care of setting up all the required paths.
*/
// Configure RequireJS
requirejs.config({
baseUrl: "Scripts",
paths: {
jquery: [
//If the CDN fails, load it from the following
'jquery-3.1.1'
]
}
});
require(['home'], function (Methods) {
Methods.doSomething();
})
home.js
define(['jquery'], function ($) {
$('#Button1').on("click", function () {
$('#foo').text('[changed by jQuery]');
});
var Methods = {
doSomething: function () {
alert('i just did something');
}
};
return Methods;
});
Resource for code Go
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 can not understand why and what this error is there - du you know why?
Update: I am running this in an nginx docker container.
Error message:
Uncaught Error: Parse Error: Line 10: Unexpected token ILLEGAL
at http://x.x.x.x/scripts/example.js:10:undefined
enter code here... R OTHER DEALINGS IN THE SOFTW
index.html
<!DOCTYPE html>
<html>
<head>
<title>Hello React</title>
<!-- Not present in the tutorial. Just for basic styling. -->
<link rel="stylesheet" href="css/base.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.13.0/JSXTransformer.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/0.3.2/marked.min.js"></script>
</head>
<body>
<div id="content"></div>
<script type="text/jsx;harmony=true" src="scripts/example.js"></script>
</body>
</html>
script/example.js
var Simple = React.createClass({
getInitialState: function(){
return { count: 0 };
},
handleMouseDown: function(){
alert('I was told: ' + this.props.message);
this.setState({ count: this.state.count + 1});
},
render: function(){
return <div>
<div className="clicker" onMouseDown={this.handleMouseDown}>
Give me the message!
</div>
<div className="message">Message conveyed
<span className="count">{this.state.count}</span> time(s)</div>
</div>
;
}
});
React.render(<Simple message="Keep it Simple"/>,
document.body);
I run in NGINX no problem, I doubt this is an issue, but you never know if it's somehow a JSX compiler issue. Can you try the below and see if it's the same result in your environment?
var Simple = React.createClass({
getInitialState: function(){
return { count: 0 };
},
handleMouseDown: function(){
alert('I was told: ' + this.props.message);
this.setState({ count: this.state.count + 1});
},
render: function(){
render (
<div>
<div className="clicker" onMouseDown={this.handleMouseDown}>
Give me the message!
</div>
<div className="message">Message conveyed
<span className="count">{this.state.count}</span> time(s)</div>
</div>
)
}
});
React.render(<Simple message="Keep it Simple"/>,
document.body);
Problem:
nginx was caching
Solution:
Set nginx.conf setting to "expires off;"
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
Have installed the angularjs and Twitter.Bootstrap packages succesfully
This is my index.html:
<!DOCTYPE html>
<html ng-app="TodoApp" xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="Scripts/jquery-1.9.1.js"></script>
<script src="Scripts/bootstrap.js"></script>
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-resource.js"></script>
<script src="Scripts/app.js"></script>
<link rel="stylesheet" type="text/css" href="Content/bootstrap.css" />
<title>Amazing Todo</title>
</head>
<body>
<div class="container">
<div ng-view></div>
</div>
</body>
</html>
This is my app.js:
var TodoApp = angular.module("TodoApp", []).
config(function ($routeProvider) {
$routeProvider.
when('/', { controller: ListCtrl, templateUrl: 'list.html' }).
otherwise({ redirectTo: '/' });
});
var ListCtrl = function ($scope, $location) {
$scope.test = "testing";
};
And, this is my list.html:
<h1>Test: {{test}}</h1>
This should work fine. However the index.html is not showing the content of list.html. I think the angularjs part is not working properly.
No idea about what am i doing wrong?
Once you have defined a module, you need to define your controllers for that module and not independently.
Thus, your controller should be rewritten as:
TodoApp.controller('ListCtrl', [ '$scope', '$location',
function ($scope, $location) {
$scope.test = "Testing";
}
]);
This should show the view in question.
I would say, that if you check errors in console (in Chrome or IE press F12) you should see:
...Failed to instantiate module TodoApp due to:
Error: [$injector:unpr] Unknown provider: $routeProvider...
The reason for this expectation is that we ask IoC to inject $routeProvider while not correctly listing dependent modules. This is the above code:
var TodoApp = angular
// here we say: we do not need any other module
.module("TodoApp", [])
// here we ask: inject $routeProvider from other module
.config(function ($routeProvider)
So to make it runing we have to include the module 'ngRoute'
var TodoApp = angular
// here we say: we need these modules to make our module working properly
.module("TodoApp", [
'ngRoute'
])
// now we can ask for the provider,
// using minification-safe syntax
.config(
[ '$routeProvider',
function ($routeProvider) {
$routeProvider.
...
}]);
And also do not forget to also reference this module scripts:
<script src="Scripts/angular.js"></script>
<script src="Scripts/angular-resource.js"></script>
<!-- here we have to load this module -->
<script src="Scripts/angular-route.js"></script>
What is your directory structure can you check if list.html is in the same directory as index.html, if not specify a relative path from the application root?
Since no one has posted a full correct answer to this question and it hasn't been closed yet, here is another answer.
This is your function:
var ListCtrl = function ($scope, $location) {
$scope.test = "testing";
};
This is a bare function, which isn't of much use. You need a controller so that Angular knows what to do with {{ test }}:
<div ng-controller="someController">
<h1>{{ test }}</h1>
</div>
If you insist on keeping the function as a separate variable, you could do so and still have a controller:
var ListCtrl = function ($scope, $location) {
$scope.test = "testing";
};
TodoApp.controller('someController', ListCtrl);
This also works.
Despite of this, your UI won't show, as there's an error in it:
var TodoApp = angular.module("TodoApp", [])
You're using $routeProvider and .when(),.otherwise(), for which you need ngRoute as a dependency:
var TodoApp = angular.module("TodoApp", ['ngRoute'])
Your app should work after that.