Error with google sign in button - angularjs

So I have this code:
HTML:
<html ng-app="MyApp" lang="en">
<head>
<title ng-controller="MainController" ng-bind="organisation"></title>
<link ng-controller="MainController" rel="icon" ng-href="{{ logo }}" />
<script src="https://www.gstatic.com/firebasejs/3.2.0/firebase.js"></script>
<script>
// Initialize Firebase
var config = {
apiKey: "AIzaSyD1mVN9oiWvgp6Zdp5e1pKOiLfdXNplcFo",
authDomain: "testing-environment-98032.firebaseapp.com",
databaseURL: "https://testing-environment-98032.firebaseio.com",
storageBucket: "testing-environment-98032.appspot.com",
};
firebase.initializeApp(config);
</script>
<script src="scripts/angular.min.js"></script>
<script src="scripts/angular-sanitize.min.js"></script>
<link rel="stylesheet" href="stylesheets/index.css" />
</head>
<body ng-controller="MainController" ng-init="initialize()">
<div id="googleSignIn" ng-style="googleSignInStyle" ng-click="signUserIn()" ng-bind="googleSignInText"></div>
<span ng-click="signOut()" >Sign Out!</span>
<article id="scrollSpeedValue" class="valuePasser"><?php echo $scrollSpeed; ?></article>
<div id="h1-margin"> </div>
<center><span class="h1"><b ng-bind="organisation"></b></span></center>
<div class="main">
<span ng-bind-html="generateNavBar(navBar.common, navBar.common[0])"></span>
<marquee id="EventsMarquee" class="infoBanner" direction="left" scrollamount="10">Events here! Set initial speed to 1000000000</marquee>
<div class="main-body" id="main-body">
<center><i>Welcome to the -- site!</i></center><br>
<div style="width: 48%; float: left;">
Description
</div>
<div style="width: 48%; float: right;"><iframe src="http://www.google.com" style="width: 99%; height: 373px;"></iframe></div>
</div>
<div class="main-body" id="footer-links">
<center>
Resources | organisation Resources | link | Edit!
</center>
</div>
</div>
<footer>
<br>
</footer>
<script src="scripts/app.js"></script>
</body>
</html>
AngularJS:
var app = angular.module("MyApp", ["ngSanitize"]);
app.controller("MainController", ["$scope", function ($scope){
$scope.organisation = "Organisation Name";
$scope.logo = "http://www.weboniks.com/images/logos/logo5.jpg";
$scope.googleSignInStyle = {};
$scope.googleSignInText = "";
$scope.signInVariables = {
displayName: null,
email: null,
uid: null,
photoURL: null
}
$scope.navBar = {
common: [
["Home", "index.html"],
["Resources", "index.html"],
["Staff Resources", "index.html"],
[$scope.organisation + " Resources", "index.html"],
["Who we are", "index.html"]
]
}
$scope.signIn = function (){
var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider).then(function(result) {
var token = result.credential.accessToken;
var user = result.user;
var providerData = user.providerData[0];
firebase.database().ref('users/' + providerData.displayName).set({Email: providerData.email, PhotoURL: providerData.photoURL, uid: providerData.uid});
}).catch(function(error) {
var errorCode = error.code;
var errorMessage = error.message;
var email = error.email;
var credential = error.credential;
console.log ("Error! Error code: " + errorCode + ", Email: " + email + ", Credential: " + credential + ". That's all we know.");
});
}
$scope.onSignIn = function (){
var providerData = firebase.auth().currentUser.providerData[0];
if (providerData.photoURL == null)
{
$scope.googleSignInStyle["background"] = "url(../images/img_default_profile.png)";
}
else
{
$scope.googleSignInStyle["background"] = providerData.photoURL;
}
$scope.googleSignInStyle["background-size"] = "100%";
$scope.googleSignInStyle["background-repeat"] = "no-repeat";
$scope.googleSignInStyle["border-radius"] = "100%";
$scope.googleSignInStyle["width"] = "4.5%";
$scope.googleSignInStyle["height"] = "9%";
$scope.googleSignInStyle["cursor"] = "default";
}
$scope.checkSignIn = function (){
var user = firebase.auth().currentUser;
if (user == null)
{
setTimeout(function (){ $scope.checkSignIn(); }, 1);
}
else
{
$scope.onSignIn();
}
}
$scope.signUserIn = function (){
var user = firebase.auth().currentUser;
if (user == null)
{
$scope.signIn();
setTimeout(function (){ $scope.checkSignIn() }, 10000);
}
else
{
$scope.onSignIn();
}
}
$scope.signOut = function (){
firebase.auth().signOut();
$scope.googleSignInText = "";
$scope.googleSignInStyle["background"] = "url(../images/btn_google_signin_dark_normal_web#2x.png)";
$scope.googleSignInStyle["background-size"] = "100%";
$scope.googleSignInStyle["background-repeat"] = "no-repeat";
$scope.googleSignInStyle["border-radius"] = "0%";
$scope.googleSignInStyle["width"] = "12%";
$scope.googleSignInStyle["height"] = "6%";
$scope.googleSignInStyle["cursor"] = "default";
$scope.googleSignInStyle["cursor"] = "pointer";
}
$scope.generateNavBar = function (items, current){
var navigator = '<nav><ul><b>';
for (i = 0; i < items.length; i++)
{
if (items[i] == current)
{
navigator += '<li id="current">' + items[i][0] + '</li>';
}
else
{
navigator += '<li>' + items[i][0] + '</li>';
}
}
navigator += '</b></ul></nav>';
console.log (navigator);
return navigator;
}
}]);
This code is supposed to sign a user in with google and then change the sign in with google button to their profile image. It works fine, the only issue is that the first time you click the sign in button it only signs you in. Then you have to click it again to change the button to the users image. Is there something I have done wrong?

Related

React-share. Throws error TypeError: Super expression must either be null or a function, not undefined when trying to use it in require

I am new in ReactJs and trying to learn it. I installed a package of react-share. Since i am trying to edit someone else's code i am not able to import the package due to webpack I believe. Every time i try to import a package I receive an error saying the import should always be on top of the script. I tried using require and I get this error in Console
TypeError: Super expression must either be null or a function, not undefined
My code looks like this:
"use strict";
require('./../../../assets/styles/components/thread.less');
var reactShare = require('react-share');
var React = require('react');
var ReactDOM = require('react-dom');
var Fluxxor = require('fluxxor');
var _ = require("lodash");
var FluxMixin = Fluxxor.FluxMixin(React);
var StoreWatchMixin = Fluxxor.StoreWatchMixin;
var routerShape = require('react-router').routerShape;
var MicroAudioViews = require('./../../constants/MicroAudioViews');
var AudioModes = require("./../../constants/AudioModes");
var i18n = require("i18next-client");
//components
var AudioVisualizer = require('../elements/AudioVisualizer');
var ReviewOverlay = require('../elements/ReviewOverlay');
var ReviewShare = require('../elements/ReviewShare');
var Menu = require('../elements/Menu');
I have to use react-share's
<FacebookShareButton url={shareLink} quote={title} className="social-media-icon">
<FacebookIcon size={32} round />
</FacebookShareButton>`
Component to share the shareLink on facebook.
Here the full code.
/*import {
FacebookShareButton,
GooglePlusShareButton,
TwitterShareButton,
WhatsappShareButton,
FacebookIcon,
TwitterIcon,
WhatsappIcon
} from 'react-share';*/
"use strict";
require('./../../../assets/styles/components/thread.less');
var reactShare = require('react-share');
var React = require('react');
var ReactDOM = require('react-dom');
var Fluxxor = require('fluxxor');
var _ = require("lodash");
var FluxMixin = Fluxxor.FluxMixin(React);
var StoreWatchMixin = Fluxxor.StoreWatchMixin;
var routerShape = require('react-router').routerShape;
var MicroAudioViews = require('./../../constants/MicroAudioViews');
var AudioModes = require("./../../constants/AudioModes");
var i18n = require("i18next-client");
//components
var AudioVisualizer = require('../elements/AudioVisualizer');
var ReviewOverlay = require('../elements/ReviewOverlay');
var ReviewShare = require('../elements/ReviewShare');
var Menu = require('../elements/Menu');
var Review = React.createClass({
mixins:[
FluxMixin,
StoreWatchMixin("ThreadStore", "RecordStore", "ReviewStore", "ApplicationStore", "SyncStore", "DemoStore", "ShareStore")
],
contextTypes: {
router: routerShape.isRequired
},
/* react interface*/
getInitialState: function() {
var selectedThreads = [];
var shareType = 'thread';
if(this.props.location.state && this.props.location.state.type == "thread") {
selectedThreads.push(this.props.location.state.threadId);
} else if(this.props.location.state && this.props.location.state.type == "share") {
shareType = 'facebook';
} else if (this.props.location.state && this.props.location.state.type == 'sharereply') {
shareType = 'sharereply';
}
return {
threadUserId: this.props.params.id,
activeShareType: shareType,
selectedThreads: selectedThreads
};
},
getStateFromFlux: function() {
var flux = this.getFlux();
var recordStoreState = flux.store('RecordStore').getState();
var threadStoreState = flux.store('ThreadStore').getState();
var appStoreState = flux.store('ApplicationStore').getState();
var reviewStoreState = flux.store('ReviewStore').getState();
var shareStoreState = flux.store('ShareStore').getState();
var demoState = flux.store('DemoStore').getState();
var activeRecord = recordStoreState.activeRecord || null;
var activeThread = threadStoreState.activeThread;
var activeRecordUser = null;
var authenticatedUser = appStoreState.demoMode? demoState.user : appStoreState.user;
var state = {
demoMode: appStoreState.demoMode,
playing: recordStoreState.playing,
recording: recordStoreState.recording,
activeThread: activeThread,
threads: threadStoreState.threads,
authenticatedUser: authenticatedUser,
activeRecord: activeRecord,
activeShareUser: shareStoreState.user,
shareId: shareStoreState.shareId
};
return state;
},
render: function() {
var threadClass = "thread";
var fbClass = "facebook";
var explanationText, usageContent;
var finishButtonClass = 'finish-button';
if(this.state.activeShareType == "thread") {
threadClass += ' active';
explanationText = i18n.t('content:review.reviewDoneExpl', {
count: this.state.selectedThreads.length,
context: this.state.selectedThreads.length == 0 ? 'doselect' : undefined
});
finishButtonClass += this.state.selectedThreads.length == 0 ? ' inactive' : '';
var threadCards = [];
var self = this;
_.each(this.state.threads, function(thread){
var threadUser = thread.user;
var threadUserPicture = threadUser.pictures[0].source;
var userName = threadUser.firstName + ' ' + threadUser.lastName;
var styleProps = {
backgroundImage : threadUserPicture ? 'url(' + threadUserPicture + ')': 'none'
};
var cls = "thread card" + (self.state.selectedThreads.indexOf(thread.id) != -1? " selected" : "");
threadCards.push(<div key={thread.id} className={cls} onClick={self.onThreadCardSelected} data-thread-id={thread.id}>
<div className='pic' style={styleProps}></div>
<div className='name'>{userName}</div>
<div className='checked micro-audio-icon-check'></div>
</div>);
});
//if thread cards array is null then we are displaying the required text
if(threadCards.length==0){
var text= "Du hast noch keine Freunde in audiyoh hinzugefugt (gehe dafur zur Suche).";
//displaying the content
usageContent = (
<div className="usage-target-container">
<p className="chat-text">{text} <br/>Uber <img className="share-icon" src={require('./../../../assets/images/share-active.png')} /> Teilen kannst du deine Aufnahme in aderen Kanale teilen.</p>
</div>);
//displaying the button
var finishContainer = <div className="finish-container">
<div className={finishButtonClass} >Fertige</div>
<div className="finish-text"><p className="chat-underbtn-text">Mindestens <b> ein Gesprach <br/> wahlen,</b> dem die Aufnahme <br/> hinzugefugt werden soll</p></div>
</div>;
}else{
usageContent = (
<div className="usage-target-container">
{threadCards}
</div>);
}
} else {
fbClass += ' active';
finishButtonClass += ' facebook';
explanationText = i18n.t('content:review.facebookExplanation');
//displaying the input box with the link and copy button
console.log("THe shareStoreState is " + this.state.shareId);
//the shareId is generate asynchroneously, so this.state.shareId can be null
if(typeof this.state.shareId === "string") {
//the link can be created like this:
var shareLink = window.location.origin + '/shared/' + this.state.shareId;
}
var usageContent = (
<div className="usage-target-container">
<div className="socialLinkContainer">
<p> Link zum Teilen </p>
<input className="copylink" type="text" value={shareLink} id="shareLink" /><br/>
<input className="copybtn" type="button" onClick={this.copytoclipboard} value="Link kopieren" />
</div>
</div>);
var finishContainer = <div className="finish-container">
<div className="social-media">
/*<img className="social-media-icon" src={require('./../../../assets/images/facebook.png')} />*/
<FacebookShareButton
url={shareLink}
quote={title}
className="social-media-icon">
<FacebookIcon
size={32}
round />
</FacebookShareButton>
<img className="social-media-icon" src={require('./../../../assets/images/whatsapp.png')} />
<img className="social-media-icon" src={require('./../../../assets/images/twitter.png')} />
<img className="social-media-icon" src={require('./../../../assets/images/instagram.png')} />
</div>
</div>;
}
var targetSwitchElements = [
<div title={i18n.t('content:review.sharethread')}
key="thread"
className={threadClass}
onClick={this.activateThreadShareType}><span>audiyoh-chat</span></div>,<br/>,
<div title={i18n.t('content:review.sharefb')}
key="facebook"
className={fbClass}
onClick={this.activateFBShareType}><span>Teilen</span></div>
];
//we either want to save a profile record a share response, so we dont need the fb/thread switch and thread cards
if(this.props.location.state && ["profile", "sharereply"].indexOf(this.props.location.state.type) != -1) {
var buttonText = i18n.t('content:review.profile');
if(this.props.location.state.type == "sharereply"){
buttonText = i18n.t('content:review.share', {name: this.state.activeShareUser.firstName});
}
targetSwitchElements = <div className="profile-record" onClick={this.onFinishRecord}>{buttonText}</div>;
usageContent = null;
finishContainer = null;
}
return (
<div className="ma-reviewing">
<div className="review-controls">
<div className="row">
<div className="col-3">
<a title={i18n.t('content:review.delete')} className="delete" onClick={this.deleteRecording}></a>
<a title={i18n.t('content:review.redo')} className="record" onClick={this.onRecordButtonClick}></a>
</div>
<div className="col-6">
<div className="review-container">
<ReviewOverlay
activeRecordUser={this.state.authenticatedUser}
record={this.state.activeRecord}
/>
</div>
</div>
{finishContainer}
<div className="col-3">
<div className="target-switch">
<p>Weiter mit der Aufnahme</p>
{targetSwitchElements}
</div>
</div>
</div>
</div>
<div className="upper" ref="upper">
<Menu location={this.props.location} />
<div className="menu">
</div>
</div>
<div className="upperguard" ref="upperguard"></div>
<div className="lower" ref="lower">
<div className="sizing-wrapper">
{usageContent}
</div>
</div>
</div>
);
},
deleteRecording: function(e) {
e.preventDefault();
if(this.props.location && this.props.location.state.userId) {
this.context.router.push({
pathname: "/thread/" + this.props.location.state.userId,
state: this.props.location.state
});
}
else {
this.context.router.push({
pathname: "/profile",
state: this.props.location.state
});
}
},
onRecordButtonClick: function(e) {
e.preventDefault();
this.context.router.push({
pathname: "/record",
state: this.props.location.state
});
},
onThreadCardSelected: function(syntheticEvent, reactId, e) {
var target = syntheticEvent.target.parentNode;
var threadId = target.getAttribute("data-thread-id");
var idx = this.state.selectedThreads.indexOf(threadId);
if(idx != -1) {
this.state.selectedThreads.splice(idx, 1);
this.setState({
selectedThreads: [].concat(this.state.selectedThreads)
});
}
else {
this.setState({
selectedThreads: [threadId].concat(this.state.selectedThreads)
});
}
},
activateThreadShareType: function() {
if(this.state.activeShareType == "thread") {
return;
}
this.setState({
activeShareType: 'thread'
});
},
activateFBShareType: function() {
if(this.state.activeShareType == "facebook") {
return;
}
this.setState({
activeShareType: 'facebook'
});
//this will store the record and generate a shareId
this.getFlux().actions.record.local.saveRecording({
type: "share"
});
/*var state1 = this.context.router.push({
pathname: '/review',
state: {
type: "profile",
role: "main"
}
});*/
//console.log("the state1 is " + state1);
//this.getFlux().actions.record.local.saveRecording(state1);
},
copytoclipboard: function(){
var copyText = document.getElementById("shareLink");
copyText.select();
document.execCommand("copy");
console.log("Copied the text: " + copyText.value);
},
onFinishRecord: function(e) {
if(e.target.classList.contains('inactive')) {
return;
}
if(this.props.location.state && ["profile", "sharereply"].indexOf(this.props.location.state.type) != -1) {
console.log(this.props.location.state);
this.getFlux().actions.record.local.saveRecording(this.props.location.state);
}
else if(this.state.activeShareType == "facebook") {
this.getFlux().actions.record.local.saveRecording({
type: "share"
});
}
else {
var data = {
type: "thread",
threadIds: this.state.selectedThreads
};
//we started recording from a thread, so we pass the userId to be able to return to this thread
//after saving
if(this.props.location.state && this.props.location.state.type == "thread") {
data.userId = this.props.location.state.userId;
}
this.getFlux().actions.record.local.saveRecording(data);
}
}
});
module.exports = Review;
I found my error!
The problem was that I initialized the require('react-share') in a variable reactShare and was using the component as
<FacebookShareButton url={shareLink} quote={title} className="social-media-icon">
<FacebookIcon size={32} round />
</FacebookShareButton>`
Instead, I should have initialized the require statement as
var FacebookShareButton = require('react-share');
Because of not declaring it properly React was yelling on me.
I hope this will save someones precious time. Cheers!

Error in calculating distance traveld by user

I'm a fresher for ionic and angularjs, I'm developing a tracking app, in which I am not able to calculate the tracked distance and store it in database.
here is my index.html
<!DOCTYPE html>
<html ng-app="starter">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link rel="manifest" href="manifest.json">
<link href="css/ionic.app.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="lib/ngCordova/ng-cordova.js"></script>
<script src="cordova.js"></script>
<script src="js/app.js"></script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAHe3efHByU2G1ECBpenC8ZpiXlpO7GFXA "></script>
</head>
<body ng-controller="MapCtrl">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Ionic Maps</h1>
</ion-header-bar>
<ion-content ng-init="first(User)">
<div class="padding">
<button class="button button-large button-calm" ng-click="starttrack(User)">Start</button>
<button class="button button-large button-assertive" ng-click="endtrack(User)">End</button>
</div>
<div>coordinates = {{getText(User)}}</div>
<button class="button button-small button-balanced" ng-click="dist()">Show distance</button>
</ion-content>
</ion-pane>
</body>
</html>
here is my app.js
.factory('AllServices', function($http) {
return {
drivertrackFunction: function(User) {
var data = { coordinates: User.coordinates,
dis: User.dis};
var link = 'http://localhost/track.php';
return $http.post(link,data);
}
};
})
.controller('MapCtrl', function($scope, filterFilter, $state, $cordovaGeolocation, $interval, AllServices) {
$scope.User = {};
$scope.User.mysrclat= 0;
$scope.User.mysrclong = 0;
$scope.User.timer = "";
$scope.addstring=[];
$scope.addstring1 = [];
$scope.User.string1="";
$scope.User.coordinates=undefined;
$scope.User.string3="";
$scope.lat1 = "";
$scope.lon1 = "";
$scope.lat2 = "";
$scope.lon2 = "";
$scope.User.d = "";
$scope.User.totalDis="";
$scope.originals = [];
$scope.User.temp = 0;
$scope.points = "";
$scope.User.pLen = "";
$scope.User.len = "";
$scope.User.origin1 = "";
$scope.User.destinationB = "";
$scope.User.geocoder = "";
$scope.User.service = "";
$scope.User.originList ="";
$scope.User.destinationList = "";
$scope.User.outputDiv = "";
$scope.User.TotDis = "";
$scope.User.TotDur = "";
$scope.User.dis = 0;
$scope.first = function(User) {
if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
$scope.User.mysrclat = position.coords.latitude;
$scope.User.mysrclong = position.coords.longitude;
$scope.User.string1 = $scope.User.mysrclat + "," + $scope.User.mysrclong;
console.log($scope.User.mysrclat);
});
}
};
$scope.track = function(User) {
$scope.first(User);
};
function distance(User) {
var R = 6371; // km (change this constant to get miles)
var dLat = ($scope.lat2-$scope.lat1) * Math.PI / 180;
var dLon = ($scope.lon2-$scope.lon1) * Math.PI / 180;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos($scope.lat1 * Math.PI / 180 ) * Math.cos($scope.lat2 * Math.PI / 180 ) * Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
$scope.User.d = R * c;
if ($scope.User.d>1) {
return Math.round($scope.d)+"km";
}
else {
if ($scope.User.d<=1) {
return Math.round($scope.d*1000)+"m";
}
}
return $scope.User.d;
};
$scope.starttrack = function(User) {
$scope.track(User);
$scope.addstring.push($scope.User.string1);
$scope.addstring1.push($scope.User.string1);
var values = $scope.User.string1.split(",");
$scope.lat1 = $scope.User.mysrclat;
$scope.lon1 = $scope.User.mysrclong;
$scope.lat2 = values[0];
$scope.lon2 = values[1];
distance();
$scope.User.timer = $interval(function() {
if($scope.addstring != "") {
$scope.track(User);
$scope.lat1 = $scope.lat2;
$scope.lon1 = $scope.lon2;
$scope.lat2 = $scope.User.mysrclat;
$scope.lon2 = $scope.User.mysrclong;
distance();
console.log($scope.User.d);
$scope.User.dis = $scope.User.dis + $scope.User.d;
$scope.addstring.push("|" + $scope.User.string1);
$scope.addstring1.push($scope.User.string1);
}
}, 10000);
};
$scope.getText = function(User){
return $scope.addstring.join("");
};
$scope.endtrack = function(User, d) {
if(angular.isDefined($scope.User.timer)) {
$interval.cancel($scope.User.timer);
$scope.User.timer = undefined;
$scope.User.string2 = $scope.addstring[0];
for(var i=1; i<($scope.addstring).length; i++) {
$scope.User.string2 = $scope.User.string2 + $scope.addstring[i];
}
$scope.User.coordinates = $scope.User.string2;
$scope.User.dis = $scope.User.dis + " KM";
console.log($scope.User.dis);
AllServices.drivertrackFunction(User)
.then(function(response) {
})
.catch(function(error) {
console.log(error);
});
}
};
$scope.dist = function() {
distance();
console.log($scope.User.d, "Km");
};
})
and this is my php code
<?php
include("connection.php");
$data = json_decode(file_get_contents("php://input"));
$coordinates = $data->coordinates;
$dis = $data->dis;
$q = "INSERT INTO track (Coordinates, Distance) VALUES (:coordinates, :dis)";
$query = $db->prepare($q);
$execute = $query->execute(array(
":coordinates" => $coordinates,
":dis" => $dis
));
echo json_encode($data);
?>

Change Different type of Attributes for Dynamically added every element

How can I Change (type) Attribute for each added dynamic buttons? In below code, label names were changing perfectly, but when i am trying to change button types it is applying to all added dynamic buttons,
My requirement is have to change every button type with different types (means: first added button type to submit, second added type to reset, third added button to cancel). but in my code if i change second button type to 'Reset' at the same time the first button type also going to Reset type... can u please tell me how can i change button type for every added element ...
Working DEMO
Updated:
var app = angular.module('myapp', ['ngSanitize']);
app.controller('MainCtrl', function($scope, $compile) {
var counter = 0;
$scope.buttonFields = [];
$scope.add_Button = function(index) {
$scope.buttonFields[counter] = {button: 'Submit'};
var buttonhtml = '<div ng-click="selectButton(buttonFields[\'' + counter + '\'])"><button id="button_Type">{{buttonFields[' + counter + '].button}}</button>//click//</div>';
var button = $compile(buttonhtml)($scope);
angular.element(document.getElementById('add')).append(button);
$scope.changeTosubmit = function (val) {
$scope.buttonField = val;
var els = document.body.querySelectorAll('#button_Type');
for (var i = 0, ils = els.length; i < ils; i++) {
var el = els[i];
el.setAttribute("type", "submit");
compile(el);
}
};
$scope.changeToreset = function (val) {
$scope.buttonField = val;
var els = document.body.querySelectorAll('#button_Type');
for (var i = 0, ils = els.length; i < ils; i++) {
var el = els[i];
el.setAttribute("type", "reset");
compile(el);
}
};
$scope.changeTocancel = function (val) {
$scope.buttonField = val;
var els = document.body.querySelectorAll('#button_Type');
for (var i = 0, ils = els.length; i < ils; i++) {
var el = els[i];
el.setAttribute("type", "cancel");
compile(el);
}
};
++counter;
};
$scope.selectButton = function (val) {
$scope.buttonField = val;
$scope.showButton_Types = true;
};
});
function compile(element) {
var el = angular.element(element);
$scope = el.scope();
$injector = el.injector();
$injector.invoke(function ($compile) {
$compile(el)($scope);
});
};
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<script src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script src="https://code.angularjs.org/1.5.0-rc.0/angular-sanitize.min.js"></script>
</head>
<body ng-controller="MainCtrl">
<button ng-click="add_Button($index)">Add Buttons</button>
<hr>
<div id="add"></div>
<form ng-show="showButton_Types">
<div>
<label>Button Name(?)</label><br/>
<input ng-model="buttonField.button">
</div>
<div>
<label>change button types(?)</label><br/>
<input ng-click="changeTosubmit(buttonFields['' + counter + ''])" name="submit" type="radio"> Submit
<input ng-click="changeToreset(buttonFields['' + counter + ''])" name="submit" type="radio"> Reset
<input ng-click="changeTocancel(buttonFields['' + counter + ''])" name="submit" type="radio"> Cancel
</div>
</form>
</body>
</html>

How to Keep track of all clicks on page in ionic application?

I have created simple page which contains check boxes. On this page user can check and uncheck boxes multiple times. I want to keep track of all these events? How Can I do that?
here is my code.
app.js
var pmApp = angular.module('pmApp', ['ionic']);
pmApp.controller('CheckboxController', function($scope) {
$scope.devList = [
{ text: "Device & app history", details : "Allows the app to view one or more of: information about activity on the device, which apps are running, browsing history and bookmarks" ,checked: true },
{ text: "Identity", details: "Uses one or more of: accounts on the device, profile data", checked: false },
{ text: "Calendar", details: "Uses calendar information", checked: false },
{ text: "Contact", details: "Uses contact information", checked: false },
{ text: "Location", details: "Uses the device's location", checked: false },
{ text: "SMS", details: "Uses one or more of: SMS, MMS. Charges may apply.", checked: false }
];
$scope.selection=[];
// toggle selection for a given employee by name
$scope.toggleSelection = function toggleSelection(item) {
var idx = $scope.selection.indexOf(item);
// is currently selected
if (idx > -1) {
$scope.selection.splice(idx, 1);
}
// is newly selected
else {
$scope.selection.push(item);
}
};
});
index.html
<div class="list" ng-controller="CheckboxController">
<ion-checkbox ng-repeat="item in devList"
ng-model="item.checked"
ng-checked="selection.indexOf(item) > -1"
ng-click="toggleSelection(item)"
>
{{ item.text }}
<h3 class="item-text-wrap"> {{ item.details }}</h3>
</ion-checkbox>
<div class="item">
<pre ng-bind="selection | json"></pre>
</div>
</div>
Thanks in advance, any help would be appreciated.
Regards
You can use https://docs.angularjs.org/api/ng/directive/ngMouseover to make a counter for mouse hovers on all your elements: and then use
https://docs.angularjs.org/api/ng/directive/ngClick to record clicks and https://docs.angularjs.org/api/ng/directive/ngMousemove to record the mouse being moved and get the position:
Everything Used:
ng-click
ng-dblclick
ng-mousedown
ng-mouseup
ng-mouseenter
ng-mouseleave
ng-mousemove
ng-mouseover
Here is some example code:
HTML:
<body ng-app="mainModule">
<div ng-controller="mainController">
<h3>1. Click</h3>
<button id="firstBtn" ng-click="onFirstBtnClick()">Click me</button>
<strong>RESULT:</strong> {{onFirstBtnClickResult}}<br />
<br />
<h3>2. Click with Dependency Injection</h3>
<label>Type something: <input type="text" ng-model="secondBtnInput"></label>
<button id="secondBtn" ng-click="onSecondBtnClick(secondBtnInput)">Click me</button><br />
<strong>RESULT:</strong> {{onSecondBtnClickResult}}<br />
<br />
<h3>3. Double click</h3>
Double-click the square<br />
<img src="images/square.png" ng-dblclick="onDblClick()" /><br />
<strong>RESULT:</strong> {{onDblClickResult}}<br />
<h3>4. Mouse down, up, enter, leave, move, over</h3>
Move the mouse on the square<br />
<img src="images/square.png"
ng-mousedown="onMouseDown($event)"
ng-mouseup="onMouseUp($event)"
ng-mouseenter="onMouseEnter($event)"
ng-mouseleave="onMouseLeave($event)"
ng-mousemove="onMouseMove($event)"
ng-mouseover="onMouseOver($event)" /><br />
<strong>MOUSE DOWN RESULT:</strong> {{onMouseDownResult}}<br />
<strong>MOUSE UP RESULT:</strong> {{onMouseUpResult}}<br />
<strong>MOUSE ENTER RESULT:</strong> {{onMouseEnterResult}}<br />
<strong>MOUSE LEAVE RESULT:</strong> {{onMouseLeaveResult}}<br />
<strong>MOUSE MOVE RESULT:</strong> {{onMouseMoveResult}}<br />
<strong>MOUSE OVER RESULT:</strong> {{onMouseOverResult}}
</div>
</body>
</html>
JS
angular.module("mainModule", [])
.controller("mainController", function ($scope)
{
// Initialization
$scope.onFirstBtnClickResult = "";
$scope.secondBtnInput = "";
$scope.onDblClickResult = "";
$scope.onMouseDownResult = "";
$scope.onMouseUpResult = "";
$scope.onMouseEnterResult = "";
$scope.onMouseLeaveResult = "";
$scope.onMouseMoveResult = "";
$scope.onMouseOverResult = "";
// Utility functions
// Accepts a MouseEvent as input and returns the x and y
// coordinates relative to the target element.
var getCrossBrowserElementCoords = function (mouseEvent)
{
var result = {
x: 0,
y: 0
};
if (!mouseEvent)
{
mouseEvent = window.event;
}
if (mouseEvent.pageX || mouseEvent.pageY)
{
result.x = mouseEvent.pageX;
result.y = mouseEvent.pageY;
}
else if (mouseEvent.clientX || mouseEvent.clientY)
{
result.x = mouseEvent.clientX + document.body.scrollLeft +
document.documentElement.scrollLeft;
result.y = mouseEvent.clientY + document.body.scrollTop +
document.documentElement.scrollTop;
}
if (mouseEvent.target)
{
var offEl = mouseEvent.target;
var offX = 0;
var offY = 0;
if (typeof(offEl.offsetParent) != "undefined")
{
while (offEl)
{
offX += offEl.offsetLeft;
offY += offEl.offsetTop;
offEl = offEl.offsetParent;
}
}
else
{
offX = offEl.x;
offY = offEl.y;
}
result.x -= offX;
result.y -= offY;
}
return result;
};
var getMouseEventResult = function (mouseEvent, mouseEventDesc)
{
var coords = getCrossBrowserElementCoords(mouseEvent);
return mouseEventDesc + " at (" + coords.x + ", " + coords.y + ")";
};
// Event handlers
$scope.onFirstBtnClick = function () {
$scope.onFirstBtnClickResult = "CLICKED";
};
$scope.onSecondBtnClick = function (value) {
$scope.onSecondBtnClickResult = "you typed '" + value + "'";
};
$scope.onDblClick = function () {
$scope.onDblClickResult = "DOUBLE-CLICKED";
};
$scope.onMouseDown = function ($event) {
$scope.onMouseDownResult = getMouseEventResult($event, "Mouse down");
};
$scope.onMouseUp = function ($event) {
$scope.onMouseUpResult = getMouseEventResult($event, "Mouse up");
};
$scope.onMouseEnter = function ($event) {
$scope.onMouseEnterResult = getMouseEventResult($event, "Mouse enter");
};
$scope.onMouseLeave = function ($event) {
$scope.onMouseLeaveResult = getMouseEventResult($event, "Mouse leave");
};
$scope.onMouseMove = function ($event) {
$scope.onMouseMoveResult = getMouseEventResult($event, "Mouse move");
};
$scope.onMouseOver = function ($event) {
$scope.onMouseOverResult = getMouseEventResult($event, "Mouse over");
};
});
You could try with the newest Ionic Analytics, if that will suit your needs. More info on their official blog post: http://docs.ionic.io/v1.0/docs/analytics-from-scratch.
Usage is pretty straight forward (from the additional docs):
.controller('MyCtrl', function($ionicAnalytics) {
$ionicAnalytics.track('Purchase Item', {
item_id: 'lpdsx,
item_name: 'Leopard Socks'
});
});

Having trouble dealing with Moment JS (Angular)

I am having trouble with Moment JS. Basically, I have some metadata for a radio station, and in my php call, I get in return the 'duration' of the song, the 'timestamp' when the song started.
I did some calculation with Moment JS to get the time when the song will be finished, and then I find the difference. However, the difference is returning a negative number, which then breaks the app.
If someone can help me that would be great.
This is my plunk http://plnkr.co/edit/joVLYdTKY5dZBOTNfTOI
Services
angular.module('starter', [])
.run(function(CurrentTrack){
CurrentTrack.refreshTrackData();
})
.controller('radioCtrl', function($scope,CurrentTrack) {
console.log(CurrentTrack);
$scope.CurrentTrack = CurrentTrack;
})
.service('CurrentTrack',function(radioData,$timeout){
var currentTrack = this;
this.setTrackData = function(trackData){
currentTrack.coverUrl = trackData.cover_url;
currentTrack.title = trackData.title;
currentTrack.artist = trackData.artist;
currentTrack.duration = moment.duration(parseInt(trackData.duration));
currentTrack.startedAt = moment.unix(trackData.timestamp);
currentTrack.finishesAt = moment(this.startedAt.add(this.duration));
currentTrack.updateIn = this.finishesAt.diff(moment());
currentTrack.refreshing = false;
return currentTrack.updateIn;
}
this.refreshTrackData = function(){
currentTrack.refreshing = true;
return radioData.refresh()
.then(currentTrack.setTrackData.bind(currentTrack))
.then(currentTrack.scheduleUpdate);
}
this.scheduleUpdate = function(ms){
console.log(ms)
$timeout(function(){
currentTrack.refreshTrackData()
},ms);
return;
}
})
Factory
.factory('radioData', function($http,$timeout) {
var retries = 0;
function parseResponse(response){
retries = 0;
if(!response.data.results){
console.log('no results')
return false;
}
console.log('refreshed...')
return response.data.results[0];
}
function makeRequest(){
console.log('refreshing...')
return $http.get('http://radio-sante-animale.fr/blah11.php? callback=jsonpCallback')
}
function retry(errResponse){
console.error('timed out');
//wait for a sec
retries++;
if(retries > 5){
throw new Error('timed out after 5 attempts!');
}
//oops
return $timeout(makeRequest,1000).then(null,retry);
}
var radioData = {
refresh: function() {
return makeRequest()
.then(null,retry)
.then(parseResponse)
.catch(function(err){
console.log(err);
});
}
};
return radioData;
});
From my side, it worked by adding Math.abs in your $timeout method
this.scheduleUpdate = function(ms) {
console.log( 'update in :' + ms)
$timeout(function() {
currentTrack.refreshTrackData()
}, Math.abs(ms));
return;
}
First I changed:
currentTrack.finishesAt = moment(this.startedAt.add(this.duration));
to:
currentTrack.finishesAt = moment(currentTrack.startedAt).add(currentTrack.duration);
In the original code you are mutating the startedAt time then cloning. I also changed all the this to currentTrack to make it more consistent.
The problem
The bug manifests when there is a difference in the time the server is keeping and the time that the client is keeping, (not because you have anything reversed).
Basically the server sends you trackData.timestamp which you parse and convert into a moment to use as your startedAt time. Then you change the trackData.duration into a moment.duration and add it to the startedAt time to get your finishesAt time.
If the time that the client is keeping is running ahead the server's time, the calculated finishesAt time will be earlier than when the actual song ends. An exaggerated example makes this more clear.
var app = angular.module('app', []);
app.controller('myController', function($scope, $timeout, $interval, Server) {
function updateTime() {
$scope.serverTime = moment().subtract(1,'s');
$scope.clientTime = moment();
}
function refreshInfo() {
Server.getSongInfo().then(parseInfo).then(scheduleRefresh);
};
function parseInfo(trackData) {
$scope.songInfo = trackData;
var startedAt = trackData.timestamp;
$scope.finishesAt = moment(startedAt).add(trackData.duration, 'ms');
$scope.updateIn = $scope.finishesAt.diff(moment());
return $scope.updateIn;
}
function scheduleRefresh(updateIn) {
if (updateIn < 0) {
$scope.bugged = true;
} else {
$scope.bugged = false;
}
$timeout(refreshInfo, updateIn);
}
$scope.songInfo = "loading";
updateTime();
refreshInfo();
$interval(updateTime, 1000);
});
app.service('Server', function($timeout, $interval) {
var song = {
duration: 5000
};
this.getSongInfo = function() {
return $timeout(function() { return this.trackData });
};
function nextSong() {
this.trackData = {
duration: song.duration,
timestamp: moment().subtract(1,'s')
};
}
nextSong();
$interval(nextSong, song.duration);
});
.container {
display: flex;
flex-flow: row wrap;
}
.row {
display: flex;
flex-direction: row;
flex-flow: space-around;
width: 100%;
}
.col {
margin: auto;
text-align: center;
}
.red {
background-color: red;
}
<head>
<script data-require="angular.js#1.4.0-beta.3" data-semver="1.4.0-beta.3" src="https://code.angularjs.org/1.4.0-beta.3/angular.js"></script>
<script data-require="moment.js#2.8.3" data-semver="2.8.3" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment.min.js"></script>
</head>
<div ng-app='app' ng-controller='myController'>
<div class="container">
<div class='row'>
<div class='col' ng-class='{red:bugged}'>
<h3>Song Info</h3>
<div>{{ songInfo }}</div>
</div>
</div>
<div class="row">
<div class='col'>
<h3>Server</h3>
<div>{{ serverTime.format("hh:mm:ss") }}</div>
</div>
<div class='col'>
<h3>Finishes At</h3>
<div>{{ finishesAt.format("hh:mm:ss") }}</div>
</div>
<div class='col'>
<h3>Update In</h3>
<div>{{ updateIn }}</div>
</div>
<div class='col'>
<h3>Client</h3>
<div>{{ clientTime.format("hh:mm:ss") }}</div>
</div>
</div>
</div>
</div>
Whenever the song info div is red, the client is in the loop where it is requesting new track info and parsing out a finish time that is earlier than the current moment, which immediately makes it request new track info.
angular.module('starter', [])
.run(function(CurrentTrack) {
CurrentTrack.refreshTrackData();
})
.controller('radioCtrl', function($scope, CurrentTrack) {
$scope.CurrentTrack = CurrentTrack;
})
.service('CurrentTrack', function(radioData, $timeout) {
var currentTrack = this;
this.setTrackData = function(trackData) {
currentTrack.coverUrl = trackData.cover_url;
currentTrack.title = trackData.title;
currentTrack.artist = trackData.artist;
currentTrack.duration = moment.duration(parseInt(trackData.duration));
currentTrack.startedAt = moment.unix(trackData.timestamp);
currentTrack.finishesAt = moment(currentTrack.startedAt).add(currentTrack.duration);
currentTrack.updateIn = currentTrack.finishesAt.diff(moment())
console.log(currentTrack, trackData);
currentTrack.refreshing = false;
return currentTrack.updateIn;
}
this.refreshTrackData = function() {
currentTrack.refreshing = true;
return radioData.refresh()
.then(currentTrack.setTrackData)
.then(currentTrack.scheduleUpdate);
}
this.scheduleUpdate = function(ms) {
console.log("update in " + ms)
$timeout(function() {
currentTrack.refreshTrackData()
}, ms);
return;
}
})
.factory('radioData', function($http, $timeout) {
var retries = 0;
function parseResponse(response) {
retries = 0;
if (!response.data.results) {
console.log('no results')
return false;
}
console.log('response parsed.')
return response.data.results[0];
}
function makeRequest() {
console.log('making request.')
return $http.get('http://radio-sante-animale.fr/blah11.php?callback=jsonpCallback')
}
function retry(errResponse) {
console.error('timed out');
//wait for a sec
retries++;
if (retries > 5) {
throw new Error('timed out after 5 attempts!');
}
//oops
return $timeout(makeRequest, 1000).then(parseResponse, retry);
}
var radioData = {
refresh: function() {
return makeRequest()
.then(parseResponse, retry)
.catch(function(err) {
console.log(err);
});
}
};
return radioData;
});
<!DOCTYPE html>
<html ng-app="starter">
<head>
<script data-require="angular.js#1.4.0-beta.3" data-semver="1.4.0-beta.3" src="https://code.angularjs.org/1.4.0-beta.3/angular.js"></script>
<script data-require="moment.js#2.8.3" data-semver="2.8.3" src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment.min.js"></script>
</head>
<body ng-controller="radioCtrl">
<h3>Current Music Information</h3>
<p ng-show="CurrentTrack.refreshing">refreshing...</p>
<img style="width:300px;height:300px;" src="{{CurrentTrack.coverUrl}}" alt="">
<p>
Title : {{ CurrentTrack.title }}
<br />Artist : {{ CurrentTrack.artist }}
<br />The song started at {{ CurrentTrack.startedAt }}
<br />Duration of the song {{ CurrentTrack.duration.asSeconds() }} seconds
<br />Finishes At {{ CurrentTrack.finishesAt }}
<br />Update In {{ CurrentTrack.updateIn }}
<br />
</body>
</html>
I'm actually not sure the best approach to fixing this problem but hopefully some one has a better answer.
A hack solution is to add more time (some acceptable amount of error) to the finishesAt to give a little leeway.
currentTrack.finishesAt = moment(currentTrack.startedAt).add(currentTrack.duration).add(1, 's');
From http://momentjs.com/docs/#/displaying/difference/
If the moment is earlier than the moment you are passing to
moment.fn.diff, the return value will be negative.
You need to reverse the dates in your diff.
EDIT: Like this -
currentTrack.updateIn = moment().diff(this.finishesAt);

Resources