I just learning about ionic. I want to make a service to my controller.
But when i make and run, there's error like this :
ionic.bundle.js:26794 Error: [$injector:unpr] Unknown provider: scoreServiceProvider <- scoreService <- datarateCtrl
Here my service.js code :
angular.module('starter.services', [])
.factory('FirstService', function($http) {
var baseUrl = 'http://192.168.0.101/xxx/grabdata/';
return {
getAll: function() {
return $http.get(baseUrl+'select.php');
},
getId: function (beritaId){
return $http.get(baseUrl+'select_id.php?id='+beritaId);
}
};
});
var StudentService = angular.module('ionicApp', [ionic])
StudentService.factory('scoreService', function($http) {
var baseUrl = 'http://192.168.0.101/xxx/grabdata/';
return {
getAll: function() {
return $http.get(baseUrl+'selectxxxx.php');
}
};
});
Here my controller.js code :
.controller('datarateCtrl', function($scope,$state, scoreService,$timeout, $ionicLoading){
$scope.showData = function() {
scoreService.getAll().success(function(data) {
$scope.datarate = data;
}).finally(function() {
$scope.$broadcast('scroll.refreshComplete');
});
};
$scope.reload = function (){
$state.go('tab.klasemen');
};
// Setup the loader
$scope.loading = $ionicLoading.show({
content: '<i class="icon ion-load-a"></i>',
animation: 'fade-in',
showBackdrop: true,
maxWidth: 50,
showDelay: 0
});
$timeout(function () {
$scope.showData();
$ionicLoading.hide();
}, 2000);
})
Here my html code (klasemen.html)
<html ng-app="ionicApp">
<ion-header-bar class="bar bar-header bar-positive" align-title="center">
<h1 class="title">xxxx</h1>
</ion-header-bar>
<ion-view>
<ion-content padding="false" class="has-header">
<ion-refresher
pulling-text="Pull to refresh..."
on-refresh="showData()">
</ion-refresher>
<div class="row header">
<div class="col">xx</div>
<div class="col">xx</div>
<div class="col">xx</div>
<div class="col">xx</div>
<div class="col">xx</div>
<div class="col">xx</div>
</div>
<div class="row" ng-repeat="data in datarate">
<div class="col">{{data.xx}}</div>
<div class="col">{{data.xx}}</div>
<div class="col">{{data.xx}}</div>
<div class="col">{{data.xx}}</div>
<div class="col">{{data.xx}}</div>
<div class="col">{{data.xx}}</div>
</div>
</ion-content>
Here my app.js
.state('tab.klasemen', {
url: '/klasemen',
views: {
'tab-klasemen': {
templateUrl: 'templates/klasemen.html',
controller: 'datarateCtrl'
}
}
})
can anyone tell what i miss or what is error with my code?
Thank you so much guys.
In your controller.js your code should like this.
angular.module('ionicApp')
.controller('datarateCtrl', function($scope,$state, scoreService,$timeout, $ionicLoading){
// script goes here
//$scope.showData
});
Related
I have to make app for listing recent photos from Flickr with option when click on any image to show that image with tags and comments it contains.
I've made this:
core.module.js
(function () {
'use strict';
angular.module('flickrApp.core', ['ui.router', 'ngResource']);
})();
core.factory.js
(function () {
'use strict';
angular
.module('flickrApp.core')
.factory('flickrImgs', flickrImgs);
flickrImgs.$inject = ['$http'];
function flickrImgs($http) {
var url = 'https://api.flickr.com/services/rest/?method=flickr.photos.getRecent&api_key=415028ef16a31ed8f70f9dc3e90964d1&extras=url_q,url_o,tags&format=json&nojsoncallback=1';
var photos;
var factory = {
getPhotos: getPhotos
};
return factory;
function getPhotos() {
return $http.get(url).then(function (response) {
factory.photos = response.data.photos.photo;
});
}
};
})();
core.controller.js
(function () {
'use strict';
angular
.module('flickrApp.core')
.controller('flickrController', flickrController);
flickrController.$inject = ['flickrImgs', '$location', '$http'];
function flickrController(flickrImgs, $location, $http) {
var fc = this;
fc.showImg = function (id) {
$location.path("/photos/" + id);
console.log(id);
};
flickrImgs.getPhotos().then(function () {
fc.photos = flickrImgs.photos;
});
}
})();
core.router.js
(function () {
'use strict';
angular
.module('flickrApp.core')
.config(config);
config.$inject = ['$stateProvider', '$urlRouterProvider'];
function config($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('main', {
abstract: true,
views: {
'header': {
templateUrl: 'app/components/core/header.html'
}
}
})
.state('main.home', {
url: '/home',
views: {
'content#': {
templateUrl: 'app/components/core/home.html',
controller: 'flickrController',
controllerAs: 'fc'
}
}
})
.state('main.singleImg', {
url: '/photos/:id',
views: {
'content#': {
templateUrl: 'app/components/core/single-img.html',
controller: 'flickrController',
controllerAs: 'fc'
}
}
});
newPhoto.$inject = ['$stateParams', 'flickrImgs'];
function newPhoto($stateParams, flickrImgs) {
return flickrImgs.get({
id: $stateParams.id
}).$promise;
}
}
})();
home.html
<div class="row col-sm-12 col-md-10 col-md-offset-1">
<div ng-repeat="photo in fc.photos | limitTo:16" class="col-sm-12 col-md-3">
<a href ng-click="fc.showImg(photo.id)">
<img class="thumbnail" ng-src="{{photo.url_q}}" width="100%">
</a>
</div>
</div>
single-img.html
<div class="row col-sm-12 col-md-10 col-md-offset-1">
<div ng-repeat="photo in fc.photos | filter : {id: photo.id} | limitTo: 1" class="col-sm-12 col-md-10 col-md-offset-1">
<a href ng-click="fc.showImg(photo.id)">
<img class="thumbnail" ng-src="{{photo.url_o}}" width="100%">
</a>
<div>Tags:
<button class="btn-primary">
{{photo.tags}}
</button>
</div>
<div>Comments:
<div>
{{photo.comments}}
</div>
</div>
</div>
</div>
When I click on image listed on home page, I want to pass that image to single-img.html template and I get image id in url, but I don't know how to pass it to html.
Any help would be appreciated.
You are missing ui-sref in in home.html
<div class="row col-sm-12 col-md-10 col-md-offset-1">
<div ng-repeat="photo in fc.photos | limitTo:16" class="col-sm-12 col-md-3">
<a ui-sref="main.singleImg({id: photo.id})">
<img class="thumbnail" ng-src="{{photo.url_q}}" width="100%">
</a>
</div>
</div>
// Updated flickrImgs factory method
function getPhotos() {
var deferred = $q.defer();
if (factory.photos) {
deferred.resolve(factory.photos);
} else {
$http.get(url).then(function(response) {
factory.photos = response.data.photos.photo;
deferred.resolve(factory.photos);
});
}
return deferred.promise;
}
// single image state with new controller
.state('main.singleImg', {
url: '/photos/:id',
views: {
'content#': {
templateUrl: 'app/components/core/single-img.html',
controller: 'singleImgController',
controllerAs: 'sic'
}
}
});
// New Controller
angular
.module('flickrApp.core')
.controller('singleImgController', singleImgController);
singleImgController.$inject = ['$stateParams', 'flickrImgs'];
function singleImgController($stateParams, flickrImgs) {
var vm = this;
flickrImgs.getPhotos()
.then(function(photos) {
angular.forEach(photos, function(photo) {
if(photo.id == $stateParams.id) {
vm.photo = photo;
}
})
});
}
// New single-img.html
<div class="row col-sm-12 col-md-8 col-md-offset-2">
<img class="thumbnail" ng-src="{{sic.photo.url_o}}" width="100%">
<div>Tags:
<div class="btn-primary">
{{sic.photo.tags}}
</div>
</div>
<div>Comments:
<div>
{{sic.photo.comments}}
</div>
</div>
</div>
Hope this helps.
I am trying to extract information through facebook API into my ionic app. It shows the messages and dates correctly into my app but no images! I have uploaded the code and demo pictures in here.
Code:
.controller('FeedCtrl', function ($scope, $stateParams, OpenFB, $ionicLoading) {
$scope.show = function () {
$scope.loading = $ionicLoading.show({
content: 'Loading User Feed(s)...'
});
};
$scope.hide = function () {
$scope.loading.hide();
};
function loadFeed() {
$scope.show();
OpenFB.get('/me/feed', {
limit: 30
})
.success(function (result) {
$scope.hide();
$scope.items = result.data;
// Used with pull-to-refresh
$scope.$broadcast('scroll.refreshComplete');
})
.error(function (data) {
$scope.hide();
alert(data.error.message);
});
}
**[<!---ionic---->][1]**
<div ng-repeat="item in items" class="list card">
<div class="item item-avatar">
<img src="https://graph.facebook.com/{{ item.from.id }}/picture" />
<h2>{{item.name}}</h2>
<p>{{item.created_time | date:'MMM d, y h:mma'}}</p>
</div>
<div class="item item-body">
<p ng-if="item.story">{{item.story}}</p>
<p>{{item.message}}</p>
<h2>{{item.from.id}}</h2>
<img ng-if="item.picture" ng-src="{{item.picture}}" />
</div>
</div>
And
I'm trying to render partial view on click, which has controller in it.
Layout/Index page :
<!DOCTYPE html>
<html lang="en" ng-app="AngularDemo">
<head>
..
</head>
<body>
<aside>
<ul class="nav nav-list" ng-controller="Navigations as nav">
<li class="">Home</li>
<li class=""> Feedbacks</li>
</ul>
</aside>
<section id="MainBody"></section>
</body>
</html>
controller.js
myApp.controller("Navigations", ["$compile", function ($compile) {
var $this = this;
this.showFeedbackDiv = function ($event) {
var compiledeHTML = $compile("<div load-Div></div>")($this);
$("#MainBody").append(compiledeHTML);
$(".Division").hide();
$("." + $(event.currentTarget).data("thisdiv")).show();
};
}]).directive('loadDiv', function () {
return {
templateUrl: '/Default/GetFeedbackView',
controller: 'Feedback'
};
});
myApp.controller("Feedback", ['AngService', '$element', function(AngService, $element) {
this.feedbackData = {};
var $this = this;
this.ShowFeedbacks = function () {
AngService.ShowFeedbacks().then(function (response) {
$this.allFeedbacks = JSON.parse(response.data);
console.log($this.allFeedbacks);
$("#ShowFeedbacksModal").modal({ backdrop: 'static', keyboard: false, show: true });
}, function (response) {
alert('Error in getting feedbacks');
});
};
}]);
partial View :
<div class="Division FedbackDiv" style="margin-top:40px" ng-controller="Feedback as fb">
<div class="page-header">
<h1>
Feedback form
<span style="cursor:pointer;" class="pull-right" ng-click="fb.ShowFeedbacks()"><i class="fa fa-adn"></i></span>
</h1>
</div>
<div class="row">
...
</div>
</div>
When i click on "show Feedbacks" nothing happens
error :
TypeError: a.$new is not a function
at g (angular.js:6970)
at M (angular.js:7618)
at angular.js:7854
at angular.js:12914
at h.$eval (angular.js:14123)
at h.$digest (angular.js:13939)
at h.$apply (angular.js:14227)
at p (angular.js:9493)
at J (angular.js:9678)
at XMLHttpRequest.t.onload (angular.js:9621)(anonymous function) # angular.js:11358
Should pass $scope in $compile; $scope should be injected into the controller; if you inspect the object this, it's not scope
instead of
var compiledeHTML = $compile("<div load-Div></div>")($this);
try
var compiledeHTML = $compile("<div load-Div></div>")($scope);
To inject $scope
myApp.controller('Navigations', ['$compile', '$scope', function ($compile, $scope) { ... }])
remove ng-controller="Feedback as fb from partial and add controllerAs : fb to loadDiv config
.directive('loadDiv', function () {
return {
templateUrl: '/Default/GetFeedbackView',
controller: 'Feedback',
controllerAs : 'fb'
};
I've created a codepen to show the problem.
When the service appModalService is used, the vm object is directly replaced with the FormController object, so none of the attributes of vm is accessible in the template and the controller associated with the vm object becomes totally useless.
The discussion(reasoning) on the appModalService can be found in ionic form.
I've added the code here for reference. Any suggestions on fixing this issue ?
HTML:
<html ng-app="ionicApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Ionic modal service</title>
<link href="http://code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="http://code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
</head>
<body ng-controller="AppCtrl as vm">
<ion-content padding="true" ng-class="{'has-footer': showFooter}">
<div class="row">
<div class="col">
<button ng-click="vm.showNonWorkingForm()" class="button button-assertive button-block">
Show Non Working Form (using appModalService)
</button>
</div>
</div>
<div class="row">
<div class="col">
<button ng-click="vm.showWorkingForm()" class="button button-assertive button-block">
Show Working Form (using ionic ModalService)
</button>
</div>
</div>
</ion-content>
<script id="non-working-form-modal.html" type="text/ng-template">
<ion-modal-view>
<ion-header-bar class="bar bar-header bar-positive">
<h1 class="title">Form</h1>
<button class="button button-clear button-primary" ng-click="vm.closeModal()">Close</button>
</ion-header-bar>
<ion-content>
<form novalidate name="vm.f" ng-submit="vm.submit()">
<div class="list">
<label class="item item-input">
<input placeholder="text" type="text" name="sometext" ng-model="vm.sometext" required>
</label>
</div>
<button type="submit" class="button button-block">
Submit
</button>
</form>
{{ vm }}
</ion-content>
</ion-modal-view>
</script>
<script id="working-form-modal.html" type="text/ng-template">
<div class="modal" ng-controller="WorkingCtrl as vm">
<ion-header-bar class="bar bar-header bar-positive">
<h1 class="title">Form</h1>
<button class="button button-clear button-primary" ng-click="closeModal()">Close</button>
</ion-header-bar>
<ion-content>
<form novalidate name="vm.f" ng-submit="vm.submit()">
<div class="list">
<label class="item item-input">
<input placeholder="text" type="text" name="sometext" ng-model="vm.sometext" required>
</label>
</div>
<button type="submit" class="button button-block">
Submit
</button>
</form>
{{ vm }}
</ion-content>
</div>
</script>
</body>
</html>
JS
angular.module('ionicApp', ['ionic'])
.controller('NonWorkingCtrl', ['$scope', 'parameters', function($scope, parameters) {
var vm = this;
/* placeholder for the FormController object */
vm.f = null;
vm.sometext = 'Added Some text';
vm.submit = function() {
if (vm.f.$valid) {
alert('NonWorkingCtrl Valid');
} else {
alert('NonWorkingCtrl InValid');
}
}
/* additional fields */
vm.field1 = 'field1';
vm.field2 = 'field2';
vm.field3 = 'field3';
vm.field4 = 'field4';
vm.field5 = 'field5';
vm.field6 = 'field6';
vm.field7 = 'field7';
}])
.controller('WorkingCtrl', ['$scope', function($scope) {
var vm = this;
/* placeholder for the FormController object */
vm.f = null;
vm.sometext = 'Added Some text';
vm.submit = function() {
if (vm.f.$valid) {
alert('WorkingCtrl Valid');
} else {
alert('WorkingCtrl InValid');
}
}
/* additional fields */
vm.field1 = 'field1';
vm.field2 = 'field2';
vm.field3 = 'field3';
vm.field4 = 'field4';
vm.field5 = 'field5';
vm.field6 = 'field6';
vm.field7 = 'field7';
}])
.controller('AppCtrl', ['$scope', 'appModalService', '$ionicModal', function($scope, appModalService, $ionicModal) {
var vm = this;
vm.showNonWorkingForm = function() {
appModalService.show('non-working-form-modal.html', 'NonWorkingCtrl as vm');
};
vm.showWorkingForm = function() {
$ionicModal.fromTemplateUrl('working-form-modal.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
$scope.modal.show();
});
$scope.closeModal = function() {
$scope.modal.hide();
$scope.modal.remove();
};
}
}])
.factory('appModalService', ['$ionicModal', '$rootScope', '$q', '$injector', '$controller', function($ionicModal, $rootScope, $q, $injector, $controller) {
return {
show: show
}
function show(templeteUrl, controller, parameters, options) {
// Grab the injector and create a new scope
var deferred = $q.defer(),
ctrlInstance,
modalScope = $rootScope.$new(),
thisScopeId = modalScope.$id,
defaultOptions = {
animation: 'slide-in-up',
focusFirstInput: false,
backdropClickToClose: true,
hardwareBackButtonClose: true,
modalCallback: null
};
options = angular.extend({}, defaultOptions, options);
$ionicModal.fromTemplateUrl(templeteUrl, {
scope: modalScope,
animation: options.animation,
focusFirstInput: options.focusFirstInput,
backdropClickToClose: options.backdropClickToClose,
hardwareBackButtonClose: options.hardwareBackButtonClose
}).then(function(modal) {
modalScope.modal = modal;
modalScope.openModal = function() {
modalScope.modal.show();
};
modalScope.closeModal = function(result) {
deferred.resolve(result);
modalScope.modal.hide();
};
modalScope.$on('modal.hidden', function(thisModal) {
if (thisModal.currentScope) {
var modalScopeId = thisModal.currentScope.$id;
if (thisScopeId === modalScopeId) {
deferred.resolve(null);
_cleanup(thisModal.currentScope);
}
}
});
// Invoke the controller
var locals = {
'$scope': modalScope,
'parameters': parameters
};
var ctrlEval = _evalController(controller);
ctrlInstance = $controller(controller, locals);
if (ctrlEval.isControllerAs) {
ctrlInstance.openModal = modalScope.openModal;
ctrlInstance.closeModal = modalScope.closeModal;
}
modalScope.modal.show()
.then(function() {
modalScope.$broadcast('modal.afterShow', modalScope.modal);
});
if (angular.isFunction(options.modalCallback)) {
options.modalCallback(modal);
}
}, function(err) {
deferred.reject(err);
});
return deferred.promise;
}
function _cleanup(scope) {
scope.$destroy();
if (scope.modal) {
scope.modal.remove();
}
}
function _evalController(ctrlName) {
var result = {
isControllerAs: false,
controllerName: '',
propName: ''
};
var fragments = (ctrlName || '').trim().split(/\s+/);
result.isControllerAs = fragments.length === 3 && (fragments[1] || '').toLowerCase() === 'as';
if (result.isControllerAs) {
result.controllerName = fragments[0];
result.propName = fragments[2];
} else {
result.controllerName = ctrlName;
}
return result;
}
}]);
#NEB I was having a similar issue around forms in ionic. I found my answer from DiscGolfer17 on the IonicForum, here
Basically, the ionic's <content> directive creates it's own isolated scope. As do forms and ionic's <ion-modal-view> directive I believe.
So to get your ng-click="vm.closeModal()" to work you need to chain a $parent in front of vm like this ng-click="$parent.vm.closeModal()"
This tells it to inherit it's parents $scope. Here is a working fork of your Plunk
I wrote a code for for my app, when a I click on the toggle to reach the second page, the url changes it took me there but nothing is appeared, just a blank page no more,
here is the app.js code
angular.module("BloodDonationApp", [
"ionic",
])
.run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
if (window.cordova && window.cordova.plugins && window.cordova.plugins.keyboard) {
cordova.plugins.keyboard.hidekeyboardAccessoryBar(true);
}
if (window.statusBar) {
//org.apache.cordova.statusbar required
statusbar.styleDefault();
}
});
})
//****************ROUTES***************//
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
abstarct: true,
url: "/home",
templateUrl: "templates/home.html"
})
.state('home.feeds', {
url: "/feeds",
views: {
"tab-feeds": {
templateUrl: "templates/feeds.html"
}
}
})
.state('home.settings', {
url: "/settings",
views: {
"tab-settings": {
templateUrl: "templates/settings.html"
}
}
})
.state('requestDetails', {
url: "/RequestDetails/:id",
view: {
"mainContent": {
templateUrl: "templates/requestDetails.html"
}
}
})
.state('requestDetails.ClientRegister', {
url: "/Client-Register/:id",
view: {
"mainContent": {
templateUrl: "templates/ClientRegister.html"
}
}
});
//if name of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/home/feeds');
})
and here is the html code of the feeds page:
<ion-view ng-controller="FeedsCtrl as vm">
<ion-content class="has-header">
<div class="card" ng-repeat="requests in vm.feeds">
<div class="item item divider" ng-click="toggleGroup(requests)"
ng-class="{active: isGroupShown(requests)}">
<div class="row row-bottom">
<div class="col">
{{requests.type}}
</div>
<div class="col">
{{requests.unitNb}} Units
</div>
</div>
</div>
<div class="item-accordion"
ng-show="isGroupShown(requests)" ng-click="goToDetails()">
<div class="row">
<div class="col-top">
Since 7 s{{requests.Date}}
</div>
<div class="col col-center col-50 col-offset-8">
<br/>{{requests.HospName}}
<br/>
{{requests.Hosplocation}}
</div>
<div class="col col-bottom">
<a class="item item-icon-right">
<div class="row">
<i class="ion-icon ion-pinpoint "></i>
</div>
<div class="row">
{{requests.HospDistance}}4km
</div>
</a>
</div>
</div>
</div>
</div>
</ion-content>
</ion-view>
and the controller for feeds:
(function () {
'use strict';
angular.module('BloodDonationApp')
.controller('FeedsCtrl', ['BloodDonationApi', '$scope', '$state', FeedsCtrl]);
function FeedsCtrl(BloodDonationApi, $scope, $state) {
var vm = this;
//start Data Binding functions//
var data = BloodDonationApi.getRequests();
console.log(data);
vm.feeds = data;
//end Data Binding//
//start Accordion function//
$scope.toggleGroup = function (requests) {
if ($scope.isGroupShown(requests)) {
$scope.shownGroup = null;
} else {
$scope.shownGroup = requests;
}
}
$scope.isGroupShown = function (requests) {
return $scope.shownGroup === requests;
}
$scope.goToDetails = function() {
$state.go('requestDetails', {id : 5});
}
//end Accordion function//
};
})();
but the request details is not appeared after clicking on the toggle its just give a blanck page, the html code :
<ion-view ng-controller="RequestDetailsCtrl as vm">
<ion-content class="has-header">
<div class="card">
<div class="item">
<div class="row">
<div class="col">
{{requests.type}}
</div>
<div class="col">
{{requests.unitNb}} Units
</div>
</div>
<div class="row">
<div class="col">
{{requests.HospName}}
</div>
<div class="col">
{{requests.Hosplocation}}
</div>
<div class="col">
4 Km Away
</div>
</div>
<button class="button button-block button-positive">
Yes, I donate <i class="ion-icon ion-thumbsup"></i>
</button>
<label>
4/5 <i class="ion-icon ion-battery-half"></i>
</label>
<div class="title">
<h3>
Last time I'd donated was since<br /> 4 months
<i class="ion-icon ion-checkmark-round"></i>
</h3>
</div>
</div>
</div>
</ion-content>
</ion-view>
the controller:
(function () {
'use strict';
angular.module('BloodDonationApp')
.controller('RequestDetailsCtrl', ['BloodDonationApi', '$stateParams', '$scope', RequestDetailsCtrl]);
function RequestDetailsCtrl(BloodDonationApi, $stateParams, $scope) {
var vm = this;
var data = BloodDonationApi.getRequests();
console.log(data);
vm.requestDetails = data;
console.log("$stateParams", $stateParams.id);
//end Data Binding//
// Get you request
};
})();
am sure that there is an error with the view code, but m not figuring it out, if anybody can help me plz.
You are inside a nested state when you are tying to load requestDetails so change your state to :
.state('requestDetails', {...})
.state('home.requestDetails', {
url: "/feeds/:id",
views: {
'tab-feeds' :{
templateUrl: "templates/requestDetails.html"
}
}
})
and your method to:
$scope.goToDetails = function() {
$state.go('home.requestDetails', {id : 5});
}
and It's working !
I've fork your git so updated working version is here if you want to pull