Trouble in Asynchronous data retrieving in Firebase using Ionic - javascript

Am absolutely new to Ionic and Firebase and was trying to create a Sample Project where I am trying to query from the Firebase Database using a check on a value. To make it clear since Firebase doesn't allow a WHERE clause in the SELECT query like conditions, so was trying to learn how to deal with that.
Here is a snapshot of my Firebase database.
My intention is simply to display on my View whichever data has the address value of 700030 in an array as we do in AngularJS using ng-repeat.
var app = angular.module('starter', ['ionic', 'firebase'])
app.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
cordova.plugins.Keyboard.disableScroll(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
app.controller('MainCtrl', function($scope, $firebaseArray){
var ref = new Firebase('https://helpee-70271.firebaseio.com');
$scope.result = $firebaseArray(ref);
ref.orderByChild("address").on("child_added", function(data) {
console.log("Initially :" + JSON.stringify($scope.result));
//console.log(data.val().address);
if(data.val().address == "700030"){
console.log(data.val().address);
$scope.result.push(data.val());
}
console.log(JSON.stringify($scope.result));
});
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!--Firebase addition start -->
<script src="https://cdn.firebase.com/js/client/2.2.2/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/angularfire/1.0.0/angularfire.min.js"></script>
<!--Firebase addition end -->
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
</head>
<body ng-app="starter">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title text-center">Ionic Blank Starter</h1>
</ion-header-bar>
<ion-content ng-controller="MainCtrl">
<div>
<div ng-repeat ="results in result">
<div>{{results.name}}</div>
<div>{{results.phNumber}}</div>
</div>
</div>
</ion-content>
</ion-pane>
</body>
</html>
Here is my Code snippet. The problem am getting is that while the checking and retrieving of data is being done properly but at the View am seeing that the array containing all the elements irrespective of the Address check is getting printed first followed by the values that should be printed.
Here is the snapshot of the View and the console of the browser
Can anyone please help me how to correct this issue and explain me where am going wrong? Would be highly indebted as am really new to this and am willing to learn. Thanks in advance!!

Your problem is that you are filling your array twice.
First with all the data using this line:
$scope.result = $firebaseArray(ref);
And secondly you add the data you actually want in the child_added listener:
$scope.result.push(data.val());
So the simple solution is to change that first line to:
$scope.result = [];

Related

I think my app.html from Angular is not being injected

I have a navbar I am trying to inject into a main page. I ran the page and checked F12 > Network which showed that the directive's templateURL (navbar.html) was either not called or not injected. There are no errors. Anyone have any idea what might be wrong with my code?
The directory structure is:
landingpage.html
js
controllers
NavController.js
directives
navappDirective.js
app.js
templates
navbar.html
Below is the code:
landingpage.html
<html>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<!--<link href="../css/landingpage.css" rel="stylesheet">-->
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--<script type="text/javascript">
alert("this works");
</script>-->
<body>
<div>
<navbar ></navbar>
</div>
<!-- Insert navbar-->
<!-- Modules -->
<script src="js/app.js"></script>
<!-- Controllers -->
<script src="js/controllers/NavController.js"></script>
<!-- Directives -->
<script src="js/directives/navappDirective.js"></script>
</body>
navappDirective.js
navapp.directive('navbar', function() {
return {
restrict: 'E',
scope: {
},
/*template: '<p>Hi</p>'*/
templateUrl: 'templates/navbar.html'
};
});
navbar.html just has a paragraph currently for testing purposes.
Thanks
ng-app is missing in landingpage.html
In you landingpage.html, please update it as below
<body ng-app="myapp">
In app.js, you probably should have
angular.module('myapp',[]);
Thank You everyone!
I had ng-app called in navbar because that is where I was using the controller information and thought that would work.
The problem was solved with the following steps:
Changed the templateURL to ../../templates/navbar.html
Called the ng-app directive on the landingpage.html This allows the page to call the app. The still have the ng-controller directive in navbar for encapsulation purposes.
After the above steps I still got a cross referencing error since you cannot call a html file from a file system. So I ran a python server using python -m http.server (for Python 3) after cd'ing to the directory holding my project. Then I could run my project using localhost:8000/

Include JS files only on iPad (Ionic)

I'm doing one Ionic App and I'm trying to load some JS/CSS files but only if is iPad. Something like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Meeting App</title>
<!-- compiled css output -->
<link href="css/ionic.app.css" rel="stylesheet">
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
// if ( is_ipad() ) :
<script src="css/just-ipad.css"></script>
<script src="js/just-ipad.js"></script>
// endif;
</head>
<body ng-app="starter">
<ion-nav-bar class="bar-stable" align-title="center">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
</body>
</html>
I think this could be do it in the index.html. There will be files used in all the iPad views but not in the mobile views.
I know that I can use the Platform Classes but this doesn't cover my needs. I'm very new in Ionic and I don't know if this is possible.
Any help is welcome!
To add OR load file dynamically
Check for device if it is ipad ?
If its true then add your desired files this way (Script OR style).
If(ionic.Platform.isIPad()){
var script = document.createElement("script");
script.src = "https://maps.google.com/maps/api/js?&callback=loadGoogleMapsApiReady";
document.getElementsByTagName("head")[0].appendChild(script);
}
Regards.
I do believe you are looking for ionic.Platform.isIPad(); method as can be seen in the link provided.
Documentation
isIPad()
Returns: boolean Whether we are running on iPad.
Usage
It seems that they have some other helper functions as can be seen from the code snippet from their site below.
angular.module('PlatformApp', ['ionic'])
.controller('PlatformCtrl', function($scope) {
ionic.Platform.ready(function(){
// will execute when device is ready, or immediately if the device is already ready.
});
var deviceInformation = ionic.Platform.device();
var isWebView = ionic.Platform.isWebView();
var isIPad = ionic.Platform.isIPad();
var isIOS = ionic.Platform.isIOS();
var isAndroid = ionic.Platform.isAndroid();
var isWindowsPhone = ionic.Platform.isWindowsPhone();
var currentPlatform = ionic.Platform.platform();
var currentPlatformVersion = ionic.Platform.version();
ionic.Platform.exitApp(); // stops the app
});
ProTip
I simply Googled the following:
ionic check platform
and clicked the first link. In the future, consider using Google first.
Reading Material
ionic.Platform

AngularJS expressions stop working when adding controller to body

I've tried building a simple Todo List app using ionic framework, however I've experienced a problem.
Whenever I add the ng-controller and ng-reapeat directives to my code, AngularJS expressions stop working.
Here is my code:
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 href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
</head>
<body>
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">ToDo</h1>
</ion-header-bar>
<ion-content>
<ion-list>
<ion-item ng-repeat="todo in TodoList">{{todo.name}}</ion-item>
</ion-list>
</ion-content>
</ion-pane>
</body>
</html>
app.js
var app = angular.module('ionicApp', ['ionic'])
app.controller('TodoCtrl', function($scope){
$scope.TodoList = [
{name: "Item 1"},
{name: "Item 2"}
]
})
You are defining the core module of your app in app.js as:
var app = angular.module('ionicApp', ['ionic'])
However, in your html, you're defining your app as:
<html ng-app="starter">
In your ng-app attribute, you're defining this app as an Angular app, and you're referencing a module which does not exist (starter). You need to specify which Angular module to use, which in your app.js at the moment is ionicApp. So try renaming starter to ionicApp, or the otherway around, as long as they have matching names.

Ionic + firebase, error Module 'firebase' is not available

I'm using the latest ionic and I want to implement a firebase backend for my app. I followed the ionic get started guide, then used bower install to install firebase and angular fire.
The error produced is:
Uncaught Error: [$injector:modulerr] Failed to instantiate module starter due to:
Error: [$injector:modulerr] Failed to instantiate module starter.controllers due to:
Error: [$injector:modulerr] Failed to instantiate module firebase due to:
Error: [$injector:nomod] Module 'firebase' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
So adding the firebase links to the index.html does not fix this issue at least for me. Using bower to install firebase it should bundle automatically just by passing in 'firebase' into the controller.js, however it produces this error. Any ideas? Thanks in advanced!
This is all that I've changed in the app thus far:
Index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
</head>
<body ng-app="starter" animation="slide-left-right-ios7">
<!--
The nav bar that will be updated as we navigate between views.
-->
<ion-nav-bar class="bar-stable nav-title-slide-ios7">
<ion-nav-back-button class="button-icon icon ion-ios7-arrow-back">
Back
</ion-nav-back-button>
</ion-nav-bar>
<!--
The views will be rendered in the <ion-nav-view> directive below
Templates are in the /templates folder (but you could also
have templates inline in this html file if you'd like).
-->
<ion-nav-view></ion-nav-view>
</body>
</html>
app.js
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})
controller.js
angular.module('starter.controllers', ['firebase'])
.controller('DashCtrl', function ($scope, $firebase) {
// TV Shows Table
var moviesRef = new Firebase("https://moviehunt.firebaseio.com/");
var sync = $firebase(moviesRef);
$scope.movies = sync.$asArray();
})
Okay, here was my solution, I started from scratch completely, instead created the ionic app with a side menu:
ionic start myApp sidemenu
then used bower and bower install firebase install angularfire
and then added the following html links to the index.html:
<script src="lib/firebase/firebase.js"></script>
<script src="lib/firebase-simple-login/firebase-simple-login.js"></script>
<script src="lib/angularfire/dist/angularfire.js"></script>

Ionic - ion-nav-view crashes in emulator

I have a problem when I try to use ion-nav-view. When I try to use it, it shows me black screen in the emulator but in ionic serve, it works perfectly for me.
I think it is a syntax error.
Also, when I create a blank project, it works perfectly in the emulator.
My project (doesn't work)
Blank project (does work)
Index.html
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="cordova.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/services.js"></script>
</head>
<body ng-app="starter" animation="slide-left-right-ios7">
<ion-nav-bar></ion-nav-bar>
<ion-nav-view></ion-nav-view>
</body>
</html>
/templates/apps/index.html
<ion-view title="Hello World">
<ion-content>
<h2>Hello World</h2>
</ion-content>
</ion-view>
app.js
// Ionic Starter App
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
// 'starter.services' is found in services.js
// 'starter.controllers' is found in controllers.js
angular.module('starter', ['ionic'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider) {
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider
// setup an abstract state for the tabs directive
.state('apps', {
url: '/',
templateUrl: '/templates/apps/index.html'
});
// if none of the above states are matched, use this as the fallbac
$urlRouterProvider.otherwise('/');
});
Try to make your templateUrl: 'templates/apps/index.html'. The forward slash makes the path absolute, which will work on ionic serve because its a web server running at the root of the domain. It doesn't work in app because files are loaded over the file:// protocol and are not at the root, so it might crash because you are referencing a file that doesn't exist and would be outside of the app and thus perhaps a permission issue.

Categories

Resources