Call AngularJS function when reading NFC tag?
I wrote a small demo app using Ionic and phonegap-nfc that can read a unique ID from an NFC tag.
Now I am trying to create a list that shows the previous read events. The event in which the tag is read must be added to this list.
I have a list where events can be added. The code looks like this:
<ion-view view-title="Usage History">
<ion-content>
<button class="button button-icon" ng-click="newTask()">
<i class="icon ion-compose"></i>
</button>
<ion-list>
<ion-item class="item-remove-animate item-avatar item-icon-right" ng-repeat="chat in chats" type="item-text-wrap" href="#/tab/tasks/{{task.id}}">
<img ng-src="{{task.pic}}">
<h2>{{task.name}}</h2>
<p>{{task.lastText}}</p>
<i class="icon ion-chevron-right icon-accessory"></i>
<ion-option-button class="button-assertive" ng-click="remove(task)">
Delete
</ion-option-button>
</ion-item>
</ion-list>
<script id="new-task.html" type="text/ng-template">
<div class="modal">
<!-- Modal header bar -->
<ion-header-bar class="bar-secondary">
<h1 class="title">New Task</h1>
<button class="button button-clear button-positive" ng-click="closeNewTask()">Cancel</button>
</ion-header-bar>
<!-- Modal content area -->
<ion-content>
<form ng-submit="createTask(task)">
<div class="list">
<label class="item item-input">
<input type="text" placeholder="What do you need to do?" ng-model="task.name">
</label>
</div>
<div class="padding">
<button type="submit" class="button button-block button-positive">Create Task</button>
</div>
</form>
</ion-content>
</div>
</script>
</ion-content>
</ion-view>
The controller looks like this:
.controller('TasksCtrl', function($scope, $ionicModal) {
$scope.tasks= [];
// Create and load the Modal
$ionicModal.fromTemplateUrl('new-task.html', function(modal) {
$scope.taskModal = modal;
}, {
scope: $scope,
animation: 'slide-in-up'
});
// Called when the form is submitted
$scope.createTask = function(task) {
$scope.chats.push({
name: task.name
});
$scope.taskModal.hide();
task.name= "";
};
// Open our new task modal
$scope.newTask = function() {
$scope.taskModal.show();
};
// Close the new task modal
$scope.closeNewTask = function() {
$scope.taskModal.hide();
};
$scope.remove = function(task) {
tasks.remove(task);
};
})
This all works great. You have a button that opens a modal option where you can add a task. Pressing the button closes the modal mode and the task is now in the list.
However, I want to automatically create a task when reading the NFC tag. I'm starting to use Angular so I don't know how to replace the "ng-click" action with something else that matches the phonegap-nfc NFC action.
The NFC event controller looks like this:
.controller('MainController', function ($scope, nfcService) {
$scope.tag = nfcService.tag;
$scope.clear = function() {
nfcService.clearTag();
};
})
.factory('nfcService', function ($rootScope, $ionicPlatform) {
var tag = {};
$ionicPlatform.ready(function() {
nfc.addTagDiscoveredListener(function (nfcEvent) {
console.log(JSON.stringify(nfcEvent.tag, null, 4));
$rootScope.$apply(function(){
angular.copy(nfcEvent.tag, tag);
// if necessary $state.go('some-route')
});
}, function () {
console.log("Listening for tags.");
}, function (reason) {
alert("Error adding NFC Listener " + reason);
});
nfc.addMimeTypeListener('', function (nfcEvent) {
console.log(JSON.stringify(nfcEvent.tag, null, 4));
$rootScope.$apply(function(){
angular.copy(nfcEvent.tag, tag);
// if necessary $state.go('some-route')
});
});
});
return {
tag: tag,
clearTag: function () {
angular.copy({}, this.tag);
}
};
});
How to do it?
source to share
Your nfcService is already listening for the tagDiscovered event, so you just need to tell TaskCtrl that something happened. To do this, you have a couple of options
- Using events / broadcasts
and. In nfcService
$rootScope.$emit('tagFound', tag);
b. In TaskCtrl
$rootScope.$on('tagFound', function(tag) {
newTask();
});
- Register a callback function
and. Add function to nfcService
var cb = null;
this.registerListener = function (callback){
this.cb = callback;
}
// inside addTagDiscoveredListener
...
cb.call(tag)
b. in taskCtrl
// inject service as nfcService
nfcService.registerListener(myCallback)
function myCallback(tag) {
newTask();
}
-
Transition to a new state
// in nfcService $ State.go ('/ tasks / add');
I usually do option 2, but remember to unregister to unblock garbage collection. Services shouldn't care about states, although option 3 is not the best way imho
source to share