$watch configuration error angularjs - angularjs

I want to display some items in several rows. The user can choose if displaying 3 or 4 items per row.
Columns get updated with the correct class, but items per row doesn't.
I've commented the $watch sentence where I think the problem is.
html file:
<!DOCTYPE html>
<html lang="en" ng-app="miTienda">
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href=" node_modules/bootstrap/dist/css/bootstrap.min.css">
</head>
<body ng-controller="TiendaController as tienda">
<div class="container">
<div class="row">
Número de columnas: <input ng-model="tienda.numColumnas" type="number" min="3" max="4" />
</div>
<div class="row" ng-repeat="fila in tienda.filas">
<div ng-class="{'col-sm-4': tienda.numColumnas == 3, 'col-sm-3': tienda.numColumnas == 4}" ng-repeat="producto in fila">
<h4>
{{producto.nombre}}
<span class="label" ng-class="tienda.stockClass({{producto.stock}})">Stock: {{producto.stock}}</span>
</h4>
<p>{{producto.precio|currency}}</p>
<img class="img-responsive" ng-src="{{producto.imagen}}">
<button type="button" class="btn btn-primary pull-right" ng-disabled="producto.stock===0">
<span class="glyphicon glyphicon-shopping-cart" aria-hidden="true"></span> Añadir al carro</button>
</div>
</div>
</div>
<script src="node_modules/angular/angular.min.js"></script>
<script src="scripts/angular-locale_es-es.js"></script>
<script src="scripts/app7c.js"></script>
</body>
</html>
js file:
'use strict';
var app = angular.module('miTienda', []);
app.controller('TiendaController', function() {
this.productos = articulos;
this.stockClass = function(stock) {
if (stock >= 15) {
return 'label-info';
} else if (stock === 0) {
return 'label-danger';
} else {
return 'label-warning';
}
};
/*las columnas que quiero por cada fila*/
this.numColumnas = 3;
this.getFilas = function(array, columns) {
var filas = [];
//http://stackoverflow.com/questions/8495687/split-array-into-chunks
var i, j, temparray, chunk = columns;
for (i = 0, j = array.length; i < j; i += chunk) {
temparray = array.slice(i, i + chunk);
filas.push(temparray);
}
return filas;
};
this.filas = this.getFilas(this.productos, this.numColumnas);
/*el observador:*/
/*this.$watch('this.numColumnas', function() {
this.filas = this.getFilas(this.productos, this.numColumnas);
});*/
});
var articulos = [{
nombre: 'FUJIFILM FinePix S8600 - negro - Cámara fotográfica digital',
precio: 149.00,
imagen: 'img/fujifilm.jpg',
stock: 5
}, {
nombre: 'PANASONIC VIERA TX-55AS650E - Televisor LED 3D Smart TV',
precio: 1499.00,
imagen: 'img/tv.jpg',
stock: 9
}, {
nombre: 'SAMSUNG Galaxy S4 Value Edition - blanco - 16 GB - Smartphone',
precio: 399.00,
imagen: 'img/fujifilm.jpg',
stock: 22,
}, {
nombre: 'WD WD Red WD40EFRX - 4 TB - Disco duro interno - 3.5"',
precio: 174.90,
imagen: 'img/disco-duro.jpg',
stock: 0,
}, {
nombre: 'SAMSUNG Gear Fit - negro - Reloj conectado',
precio: 199.00,
imagen: 'img/samsung-gear.jpg',
stock: 34,
}];

I'm guessing the problem has to do with this not referring to what you think it does within the watch callback. If you try binding this to a variable, does it work?
var self = this;
this.$watch('this.numColumnas', function() {
self.filas = self.getFilas(self.productos, self.numColumnas);
});

This way it works:
'use strict';
var app = angular.module('miTienda', []);
app.controller('TiendaController', ['$scope', function($scope) {
this.productos = articulos;
.....
var self=this;
$scope.$watch('tienda.numColumnas', function() {
self.filas = self.getFilas(self.productos, self.numColumnas);
});

Related

How to display repeated drop down based on button selection in AngularJS

I need to display a drop down along with Plus button at first time. Based on button click it should display one more combination , I mean same drop down with options excluded previous selected value which we have from the first drop down and the plus button. This action should be repeat based on plus button selection.
Here is my code:
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.init = function() {
$scope.display = false;
};
$scope.init();
$scope.records = [
{ id: "part1", part: "Frt Bumper Cover" },
{ id: "part2", part: "Frt Lwr Bumper Cover" },
{ id: "part3", part: "Frt Upr Bumper Cover" },
{ id: "part4", part: "Hood Panel" },
];
$scope.changedValue = function(key) {
// alert(key);
//var index = $scope.records.indexOf(item);
//alert(index);
$scope.records.splice(index, 1);
//delete $scope.records[key];
// alert(JSON.stringify($scope.records));
};
$scope.sample = function() {
$scope.display = true;
// alert("sample: "+$scope.display);
//alert("inside sample:::"+JSON.stringify($scope.records));
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl" ng-init="init()">
<div>
<select ng-model="selectedRecord"
ng-change="changedValue(selectedRecord)"
ng-options="record.id as record.part for record in records">
<option ng-repeat="x in records">{{x.part}}</option>
</select>
<input type="submit" value="+" ng-show="records.length!=1"
ng-click="sample()" />
</div>
<div ng-show="display">
<select ng-model="selectedRecord"
ng-change="changedValue(selectedRecord)"
ng-options="record.id as record.part for record in records">
</select>
<input type="submit" value="+" ng-show="records.length!=1"
ng-click="sample()" />
</div>
</body>
I am unable to display like that, please share your ideas to do this
My friend, i think i have a solution for your problem. :D
Its very basic code i think, so i would be happy to explain more in depth if needed.
look code here: plnkr, this is basically all the code, so its my first plunker.
$scope.originalRecords = [
{ id: "part1", part: "Frt Bumper Cover" },
{ id: "part2", part: "Frt Lwr Bumper Cover" },
{ id: "part3", part: "Frt Upr Bumper Cover" },
{ id: "part4", part: "Hood Panel" },
];
$scope.selectArray = [{selectedOption: null, options: $scope.originalRecords}];
$scope.selectedOption =[];
$scope.hideButton = false;
$scope.addNewSelect = function (arrayToSearch, selectedOption) {
var index = arrayToSearch.map(function(d) { return d['part'];}).indexOf(selectedOption);
var newRecords = arrayToSearch.slice();
newRecords.splice(index, 1);
if (newRecords.length > 0) {
$scope.selectArray.push({selectedOption: null, options: newRecords});
} else {
$scope.hideButton = true;
}
}
Hope it helps.

How can I assign a class to a report not on odd, even rows but on the change of a date column?

I have a very simple report in AngularJS:
<div class="gridHeader">
<div>User</div>
<div>Date</div>
<div>Count</div>
</div>
<div class="gridBody"
<div class="gridRow" ng-repeat="row in rps.reports">
<div>{{row.user}}</div>
<div>{{row.date}}</div>
<div>{{row.count}}</div>
</div>
</div>
The report works but it's difficult to notice when the date changes.
Is there some way that I could assign a class to the grid row so that one date grid row has one class and the next date the grid row has another class. I think this is already available for odd and even rows with Angular but here I need it to work on every date change.
I've done a different solution (PLUNKER) where whole work is inside the controller. Maybe is a little bit more of code, but you will gain a lot of performance if you have thousand records because you will avoid dirty checking of ng-class. Additionally if your report is static and it won't have any changes, you can disable the two data binding...
CONTROLLER
vm.reports = addReportCssClases();
function addReportCssClases() {
var reportsData = [...];
var classes = ['dateOdd', 'dateEven'];
var index = 0;
reportsData[0].cssClass = classes[index];
for (var i = 1; i < reportsData.length; i++) {
var row = reportsData[i];
index = (row.date !== reportsData[i-1].date) ? (1 - index) : index;
row.cssClass = classes[index] ;
}
return reportsData;
}
HTML
<div ng-repeat="row in vm.reports track by $index" class="gridRow {{::row.cssClass}}">
<div>{{::row.user}}</div>
<div>{{::row.date}}</div>
<div>{{::row.count}}</div>
</div>
You can use ng-class with a function defined in your controller. For example:
var currentColor = "color1";
$scope.getClass = function(index)
{
if (index !== 0 && $scope.data[index].date !== $scope.data[index - 1].date)
{
currentColor = currentColor == "color1" ? "color2" : "color1";
}
return currentColor;
}
And in your template:
<div class="gridRow" ng-repeat="(i, d) in data" data-ng-class="getClass(i)">
See the plunker: http://plnkr.co/edit/PPPJRJJ1jHuJOgwf9lNK
This can be done with a one line given all the dates are actually date with the same format and not date time
<div class="gridHeader">
<div>User</div>
<div>Date</div>
<div>Count</div>
</div>
<div class="gridBody">
<div ng-repeat="row in rps.reports" class="gridRow" ng-class="{'backblue':$index>0 && row.date!=rps.reports[$index-1].date}">
<div>{{row.user}}</div>
<div>{{row.date}}</div>
<div>{{row.count}}</div>
</div>
</div>
your gridRow class will have to contain the background-color
.gridRow{
//other styles
background-color:red;
}
and the class backblue will have to have only the background-color
.backblue{
background-color:blue !important;
}
IMPORTANT
This will only work if the date field is only date and does not have time. If in any case it does have time you will have to convert each datetime to date
I have created a very simple and working solution for this using angular-filter, only you need to add dynamic class on gridRow.
working jsfiddle
HTML
<div ng-repeat="row in rps.reports"
class="gridRow {{row.date | filterDate}}">
Styles
.even {
background-color: green;
color: #fff;
}
.odd {
background-color: red;
color: #000;
}
Angular-filter
myApp.filter('filterDate', function() {
var lastDate,
count = 0,
calssName = 'even';
return function(date) {
var newDate = new Date(date).toDateString();
!lastDate && (lastDate = newDate);
if (newDate != lastDate) {
if (calssName == 'even') {
calssName = 'odd';
} else {
calssName = 'even';
}
}
lastDate = newDate;
return calssName;
}
});
A modified version of #ssougnez answer by storing the current date also in addition to color:
if(!(currentDate && currentDate === data.date)){
currentColor = currentColor == "color1" ? "color2" : "color1";
currentDate = data.date;
}
Plunker: http://plnkr.co/edit/o3YVBB
This might have less impact on performance than his version.
var app = angular.module('sample', []);
app.controller('SampleController', function($scope)
{
$scope.data = [
{
user: "A",
date: "3/2/2017"
},
{
user: "B",
date: "3/4/2017"
},
{
user: "C",
date: "4/3/2017"
},
{
user: "D",
date: "4/3/2017"
},
{
user: "E",
date: "4/3/2017"
},
{
user: "F",
date: "4/2/2017"
}
];
});
.same{
background-color:#ddd;
}
.differ{
background-color:yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html ng-app="sample">
<head>
</head>
<body>
<div ng-controller="SampleController">
<table id="myTable">
<thead>
<tr>
<th>User</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in data">
<td>{{row.user}}</td>
<td class="same" ng-if="data[$index+1].date==row.date || data[$index-1].date==row.date">{{row.date}}</td>
<td class="differ" ng-if="data[$index+1].date!=row.date && data[$index-1].date!=row.date">{{row.date}}</td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
You can add the class with an expression using the ngClass directive in the view:
(function() {
'use strict';
angular.module('app', []);
})();
(function() {
'use strict';
angular.module('app').controller('MainController', MainController);
MainController.$inject = ['$scope'];
function MainController($scope) {
var date = new Date();
$scope.rps = {
reports: [{
user: 'User A',
date: date.setDate(date.getDate() + 1),
count: 5
},
{
user: 'User B',
date: date.setDate(date.getDate() + 2),
count: 10
},
{
user: 'User C',
date: date.setDate(date.getDate()),
count: 8
},
{
user: 'User D',
date: date.setDate(date.getDate() + 2),
count: 6
},
{
user: 'User E',
date: date.setDate(date.getDate()),
count: 20
},
{
user: 'User F',
date: date.setDate(date.getDate() + 3),
count: 6
}
]
};
}
})();
.gridHeader,
.gridRow {
display: table-row;
}
.gridHeader>div,
.gridRow>div {
display: table-cell;
padding: 5px 10px;
}
.className {
background: #ff0000;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js"></script>
<div ng-app="app" ng-controller="MainController as MainCtrl">
<div class="gridHeader">
<div>User</div>
<div>Date</div>
<div>Count</div>
</div>
<div class="gridBody">
<div class="gridRow" ng-repeat="row in ::rps.reports track by $index" ng-class="::{'className': $index === 0 || $index > 0 && rps.reports[$index - 1].date !== row.date}">
<div>{{::row.user}}</div>
<div>{{::row.date | date: 'dd-MM-yyyy'}}</div>
<div>{{::row.count}}</div>
</div>
</div>
</div>
Or add a boolean in the controller that you can use to trigger the className using the ngClass directive:
(function() {
'use strict';
angular.module('app', []);
})();
(function() {
'use strict';
angular.module('app').controller('MainController', MainController);
MainController.$inject = ['$scope'];
function MainController($scope) {
var date = new Date();
$scope.rps = {
reports: [{
user: 'User A',
date: date.setDate(date.getDate() + 1),
count: 5
},
{
user: 'User B',
date: date.setDate(date.getDate() + 2),
count: 10
},
{
user: 'User C',
date: date.setDate(date.getDate()),
count: 8
},
{
user: 'User D',
date: date.setDate(date.getDate() + 2),
count: 6
},
{
user: 'User E',
date: date.setDate(date.getDate()),
count: 20
},
{
user: 'User F',
date: date.setDate(date.getDate() + 3),
count: 6
}
]
};
// add the classes to the reports
addClasses($scope.rps.reports);
/*
* #name addClasses
* #type function
*
* #description
* Adds a class to a report if the date is different to the previous
*
* #param {array} reports The reports to add classes to
* #return nothing.
*/
function addClasses(reports) {
// loop through the reports to check the dates
for (var i = 0, len = reports.length; i < len; i++) {
// if the previous report a different date then the current report will have a class
reports[i].hasClass = (i === 0 || reports[i - 1].date !== reports[i].date);
}
}
}
})();
.gridHeader,
.gridRow {
display: table-row;
}
.gridHeader>div,
.gridRow>div {
display: table-cell;
padding: 5px 10px;
}
.className {
background: #ff0000;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js"></script>
<div ng-app="app" ng-controller="MainController as MainCtrl">
<div class="gridHeader">
<div>User</div>
<div>Date</div>
<div>Count</div>
</div>
<div class="gridBody">
<div class="gridRow" ng-repeat="row in ::rps.reports track by $index" ng-class="::{'className': row.hasClass}">
<div>{{::row.user}}</div>
<div>{{::row.date | date: 'dd-MM-yyyy'}}</div>
<div>{{::row.count}}</div>
</div>
</div>
</div>

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);
?>

Error with google sign in button

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?

bind nested ng-repeat to model

In the following example, I should ask for the name of six students. They will be grouped according to bedroom type.
2 -> double
1 -> single
3 -> tiple
So, it means that I'll have a array of students (6 students). I would like to get their names. I was trying to create a variable like 'count' and put as ng-model of the input and increment during the loop, but it didn't work.
full html:
<!doctype html>
<html ng-app="sampleApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body ng-controller='SampleController'>
<div ng-repeat='i in numberOfAccommodations track by $index'>
Bedroom {{$index}}
<span ng-repeat='x in numberOfStudents[$index]'>
Student {{$index}}
<input type='text' ng-model='abroadStudents[???].name' /> <!-- this input to student model -->
</span>
</div>
<input type='button' value='test' ">
<script>
angular.module('sampleApp',[]).controller('SampleController',function($scope){
$scope.abroadStudents = new Array[6];
$scope.abroadAccommodation = new Array();
$scope.abroadAccommodation.push({ "bedroomType": 2}, { "bedroomType": 1 }, {"bedroomType": 3});
$scope.numberOfAccommodations = function()
{
var arr = new Array();
for (var i = 0 ; i < $scope.abroadAccommodation.length ; i++)
{
arr.push(i);
}
return arr;
}();
$scope.numberOfStudents = function()
{
var arr = new Array();
for (var x = 0 ; x < $scope.abroadAccommodation.length ; x++)
{
var temp = 0;
var intArr = new Array();
do
{
intArr.push(temp);
temp++;
}
while(temp < $scope.abroadAccommodation[x].bedroomType);
arr.push(intArr);
}
return arr;
}();
});
</script>
</body>
</html>
I rewrote your logic to create a more logical structure of objects which does not require relying upon the $index. It creates an Array of room objects, then iterates through the array of abroadAccommodation. For each abroadAccommodation, it adds a room, and based on type, adds the appropriate number of student objects. It is then very easy to use ng-repeat to iterate through each room to identify each student.
Note I also am using angular.forEach here.
<!doctype html>
<html ng-app="sampleApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body ng-controller='SampleController'>
<div ng-repeat="room in rooms">
{{room.roomNum}}
<div ng-repeat="student in room.students">
{{student.bed}}
<input ng-model="student.name" />
</div>
</div>
Student List:
<div ng-repeat="room in rooms">
<div ng-repeat="student in room.students">
{{student.name}}
</div>
</div>
<script>
angular.module('sampleApp', []).controller('SampleController', function($scope) {
$scope.abroadAccommodation = new Array();
$scope.abroadAccommodation.push({
"bedroomType ": 2
}, {
"bedroomType ": 1
}, {
"bedroomType ": 3
});
$scope.rooms = function() {
var arr = [];
angular.forEach($scope.abroadAccommodation, function(type, count) {
var room = {
"roomNum": "room " + (count + 1),
students: []
};
angular.forEach(type, function(numBeds) {
for (i = 0; i < numBeds; i++) {
room.students.push({
"bed": "bed " + (i + 1),
"name": "student" + Math.random()
});
}
arr.push(room);
})
});
return arr;
}();
});
</script>
</body>
</html>
http://plnkr.co/edit/YaPo54NUBPk9AnZkGcCc?p=preview

Resources