I'm trying to make a little app in ionic, but it gave me that error when i call the $scope.saveClass() function from the UI.
Unable to get property 'subject' of undefined or null reference
I don't understand because he doesn't work. Premise: i'm new to ionic/angularjs developing.
I thank you in advance for helping
code (www/js/controllers.js)
angular.module('starter.controllers')
.service("DB", function() {
this.classDB = new PouchDB("classesDB");
})
.controller("AddClassCtrl", function ($scope, DB) {
$scope.saveClass = function () {
var newclass = {
"_id": $scope.class.subject,
"subject": $scope.class.subject,
"room": $scope.class.room
}
DB.classDB.put(newclass);
window.location.href = '#app/schedule'
};
})
Code (add-class.html)
<ion-content controller="AddClassCrtl">
<div class="list">
<!--Select the subject-->
<label class="item item-input item-select">
<div class="input-label">
Subject
</div>
<button class="button button-block button-positive overflowShow"> Add a subjects </button>
<select class="item-input" ng-model="class.subject" ng-selected="class.subject">
<option ng-repeat="subject in subjects">{{subject}}</option>
</select>
</label>
<!--Insert the room number-->
<label class="item item-input item-stacked-label">
<input type="text" placeholder="Room" ng-model="class.room" ng-text-change="class.room">
</label>
<div class="item">
<button ng-click="discardClass()" class="button button-block">Discard</button>
<button ng-click="saveClass()" class="button button-block">Save</button>
</div>
</div>
</ion-content>
It's probably because you didn't initialize $scope.class variable and in fact, when you try to access $scope.class.subject, $scope.class is undefined. Add this code at the beginning of your controller:
$scope.class = {};
Related
I'm trying to create a user registration with Angular, that creates a user in my Django backend. When I press the Signup button nothing happens.
This is my first time working with Angular, so I understand my syntax and logic might be completely off. But I feel like if I can learn this part, It will set me up for doing the other things I need to do with Angular.
To save myself some time I'm trying to appropriate Tivix's angular-django-auth from github into my own project, so my controller really is just the Tivix one, that I tried to shove into my own project, but I can't seem to make it work. I'm sorry if this question is stupid, but I'm still trying to learn Angular, and how all the pieces are supposed to work together.
Note: my API Server is running on localhost:8000 and Ionic is running on localhost:4400, so I don't know if that might be a problem too?
Here's my controller:
.controller('signupCtrl', ['$scope', '$stateParams', // The following is the constructor function for this page's controller. See https://docs.angularjs.org/guide/controller
// You can include any angular dependencies as parameters for this function
// TIP: Access Route Parameters for your page via $stateParams.parameterName
function ($scope, $stateParams, djangoAuth, Validate) {
$scope.model = { 'username': '', 'password': '', 'email': '' };
$scope.complete = false;
$scope.register = function (formData) {
$scope.errors = [];
Validate.form_validation(formData, $scope.errors);
if (!formData.$invalid) {
djangoAuth.register($scope.model.username, $scope.model.password1, $scope.model.password2, $scope.model.email)
.then(function (data) {
// success case
$scope.complete = true;
}, function (data) {
// error case
$scope.errors = data;
});
}
}
}])
<ion-view title="Signup" hide-nav-bar="true" id="page2" style="background-color:#F1F1F1;">
<ion-content padding="true" class="manual-ios-statusbar-padding">
<div class="spacer" style="width: 300px; height: 18px;"></div>
<div>
<img src="img/aSVlyHt1SqywcHmw4wIg_logo.svg" width="80%" height="auto" style="display: block; margin-left: auto; margin-right: auto;">
</div>
<div class="spacer" style="width: 300px; height: 59px;"></div>
<div ng-controller="signupCtrl">
<form id="signup-form1" ng-if="authenticated != true" ng-submit="register(registerForm)" novalidate class="list">
<ion-list id="signup-list1">
<label class="item item-input" id="signup-input1">
<span class="input-label">Email:</span>
<input type="email" ng-model="model.email" placeholder="">
</label>
<label class="item item-input" id="signup-input2">
<span class="input-label">Username:</span>
<input type="text" ng-model="model.username" placeholder="">
</label>
<label class="item item-input" id="signup-input3">
<span class="input-label">Password:</span>
<input type="password" ng-model="model.password1" placeholder="">
</label>
</ion-list>
<button id="signup-button12" style="left:-10px;" type="submit" class="button button-energized button-full">Sign Up</button>
</form>
</div>
<!-- <div style="margin-right:-20px;">
<button id="signup-button12" style="left:-10px;" type="submit" class="button button-energized button-full">Sign Up</button>
</div>-->
<a ui-sref="login" id="signup-button6" class="button button-positive button-block button-clear">Or login</a>
</ion-content>
</ion-view>
I have used two plugins list.min.js and list.fuzzysearch.js.
When I use it in simple list, it works fine. But when I use it in ng-repeat, it throws error like "Cannot read property 'childNodes' of undefined at ...(list.min.js:1)..
search.html
<div id="testList" class="padding" >
<label class="item item-input">
<input type="text" placeholder="Search" class="fuzzy-search">
</label>
<div ng-repeat="content in contents">
<ul class="list" >
<li><p class="keyword">{{content.ChapterName}}</p></li>
</ul>
</div>
</div>
controller
.controller('SearchCtrl', ['$scope' ,'$http', function($scope, $http) {
$http.get("js/content.json").success(function(data) {
$scope.contents = data;
var demoList = new List('testList', {
valueNames: ['keyword'],
plugins: [ListFuzzySearch()]
});
});
})
I am building an angular ionic app using meteor framework so far so good, but I am trying to update my scope using $apply method which is not updating my scope, here is my code. To be more specific the user after uploading the image calls addAvatar function() which converts the image to a base64 object using fileReader API. Which in turn must be assigned to editProfileController.cropImgSrc using $apply but its not happening.
I am trying to update scope of editProfileController.cropImgSrc
Template(directive)
<ion-view view-title="Profile Edit">
<div class="bar bar-header bar-positive">
<h1 class="title">edit your profile</h1>
</div>
<ion-content overflow-scroll="true" class="has-header">
<h4 style="color:#212121;font-family: 'proxima',sans-serif;">Edit profile</h4>
<div class="row row-center">
<div class="col col-25">
<div>
{{editProfileController.cropImgSrc}}
</div>
</div>
<div class="col">
<div class="button button-outline button-positive" ngf-select
ngf-change="editProfileController.addAvatar($files)"
ngf-multiple="false" ngf-allow-dir="false" ngf-accept="'image/*'"
ngf-drop-available="false">
edit my display picture
</div>
</div>
</div>
<div class="list">
<div class="list">
<label class="item item-input">
<span class="input-label">your name</span>
<input type="text" ng-model="editProfileController.profile.name">
</label>
<label class="item item-input">
<span class="input-label">your birthday</span>
<input type="date" ng-model="editProfileController.profile.birthday">
</label>
<label class="item item-input item-select">
<div class="input-label">
Gender
</div>
<select ng-model="editProfileController.profile.gender">
<option selected>Female</option>
<option>Male</option>
<option>Others</option>
</select>
</label>
</div>
<h5 style="color:#212121;font-family: 'proxima',sans-serif;" class="padding">Add a short Bio about you, Keep it interesting and simple!</h5>
<label class="item item-input">
<span class="input-label">Bio</span>
<input type="text" placeholder="I am a storm trooper, fighting at star wars." ng-model="editProfileController.profile.bio">
</label>
<br>
<div class="row padding">
<div class="col">
<button class="button button-outline button-positive button-block">
save my profile
</button>
</div>
</div>
</div>
</ion-content>
Controller
angular.module('appName').directive('profileedit',function(){
return{
restrict: 'E',
templateUrl: 'client/modules/profile-edit/profile-edit.html',
controllerAs: 'editProfileController',
controller: function($scope,$reactive){
$reactive(this).attach($scope);
this.helpers({
cropImgSrc: function(){
return ' ';
}
});
this.addAvatar = function(files){
if (files.length > 0) {
var reader = new FileReader();
reader.onload = function(e) {
$scope.$apply(function(){
this.cropImgSrc = e.target.result;
});
};
reader.readAsDataURL(files[0]);
}
else {
this.cropImgSrc = undefined;
}
};
}
}
});
Solution
attach this to vm above the controller definetion,
var vm = this;
The error occurs because the context of this has changed within the $scope.$apply method call.
See: this context within an event handler
A simple fix would be to save the context of this in a variable at the top of the controller's definition:
controller: function($scope,$reactive){
// save context of this in a variable
var vm = this;
$reactive(this).attach($scope);
this.helpers({
cropImgSrc: function(){
return ' ';
}
});
this.addAvatar = function(files){
if (files.length > 0) {
var reader = new FileReader();
reader.onload = function(e) {
$scope.$apply(function(){
// vm still refers to the controller here
vm.cropImgSrc = e.target.result;
});
};
reader.readAsDataURL(files[0]);
}
else {
this.cropImgSrc = undefined;
}
};
}
I am new to angular and trying to implement add to list functionality. I have a few questions
why does console.log of $scope.newChat return undefined
Is newChat available to sendChat() call due to variable hoisting.
Template
<ion-list>
<ion-item class="item-remove-animate item-avatar item-icon-right" ng-repeat="chat in chats" type="item-text-wrap" href="#/tab/chats/{{chat.id}}">
<img ng-src="{{chat.face}}" >
<h2>{{chat.name}}</h2>
<p>{{chat.lastText}}</p>
<i class="icon ion-chevron-right icon-accessory"></i>
<ion-option-button class="button-assertive" ng-click="remove(chat)">
Delete
</ion-option-button>
</ion-item>
<ion-item >
<form ng-submit="sendChat(newchat)"> <!-- this line in question 2 -->
<label class="item item-input">
<input type="text" placeholder="What do you need to do?" ng-model="newchat.lastText">
<button type="submit" class="button button-right button-positive">Send</button>
</label>
</div>
</form>
</ion-item>
</ion-list>
controller
.controller('ChatsCtrl', function($scope, Chats) {
$scope.chats = Chats.all();
$scope.remove = function(chat) {
Chats.remove(chat);
}
$scope.sendChat = function(newchat){
Chats.set(newchat);
console.log($scope.newchat); //this line in question 1
newchat.lastText = "";
}
})
1) why does console.log of $scope.newChat return undefined
you are getting newchat on scope console.log($scope.newchat); try console logging with console.log(newchat); they both are same as newchat in ng-model make it available on scope. See console after clicking send button in demo below
2)Is newChat available to sendChat() call due to variable hoisting.
No it is available due to ng-model data binding
Demo
angular.module('myApp',[])
.controller('ChatsCtrl', function($scope) {
//$scope.chats = Chats.all();
$scope.remove = function(chat) {
//Chats.remove(chat);
}
$scope.sendChat = function(newchat){
// Chats.set(newchat);
console.log($scope.newchat); //this line in question 1
newchat.lastText = "";
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="ChatsCtrl"> <form ng-submit="sendChat(newchat)"> <!-- this line in question 2 -->
<label class="item item-input">
<input type="text" placeholder="What do you need to do?" ng-model="newchat.lastText">
<button type="submit" class="button button-right button-positive">Send</button>
</label>
</form>
</div>
change your controller to following
.controller('ChatsCtrl', function($scope, Chats) {
$scope.newchat = {};
$scope.chats = Chats.all();
$scope.remove = function(chat) {
Chats.remove(chat);
}
$scope.sendChat = function(newchat){
Chats.set(newchat);
console.log($scope.newchat); //now you will have your $scope.newchat
newchat.lastText = "";
}
})
i have a list of a few radio buttons and a input, and for some reason i can't get the selected radio value.
here is my example, or jsfiddle. If you look in the console and submit the form you can see that even if you select a radio button the response is undefined, but the input value comes in ok
var SampleApp;
(function (SampleApp) {
var app = angular.module('sampleApp', ['ionic']);
app.controller('MainCtrl', function ($scope) {
$scope.tests = [{
"id": "1"
}, {
"id": "2"
}, {
"id": "3"
}];
$scope.addResource = function (settings) {
console.log(settings);
};
});
})(SampleApp || (SampleApp = {}));
<link href="http://code.ionicframework.com/1.0.0-beta.6/css/ionic.css" rel="stylesheet"/>
<script src="http://code.ionicframework.com/1.0.0-beta.6/js/ionic.bundle.js"></script>
<div>
<div ng-app="sampleApp" ng-controller="MainCtrl">
<ion-content style="display:block">
<form ng-submit="addResource(settings)">
<div class="list list-inset" ng-repeat="test in tests">
<ion-radio ng-model="settings.id" value="{{test.id}}">{{test.id}}</ion-radio>
</div>
<br/>
<div class="list" style="margin: 5px 10px;">
<label class="item item-input item-stacked-label"> <span class="input-label">Email</span>
<input type="text" ng-model="settings.email">
</label>
</div>
<button class="button button-positive">Save</button>
</form>
</ion-content>
</div>
</div>
You need to pre-initialize settings in your controller so that settings is not created inside the child scope if ng-repeat, instead it is inherited from controller scope, also use ng-value="test.id" instead of value=interpolation (value="{{test.id}}"), it binds the given expression to the value of your radio, so that when the element is selected, the ngModel of that element is set to the bound value.
var SampleApp;
(function (SampleApp) {
var app = angular.module('sampleApp', ['ionic']);
app.controller('MainCtrl', function ($scope) {
$scope.settings = {}; //Initialize model here
$scope.tests = [{
"id": "1"
}, {
"id": "2"
}, {
"id": "3"
}];
$scope.addResource = function () {
console.log($scope.settings);
};
});
})(SampleApp || (SampleApp = {}));
<link href="http://code.ionicframework.com/1.0.0-beta.6/css/ionic.css" rel="stylesheet"/>
<script src="http://code.ionicframework.com/1.0.0-beta.6/js/ionic.bundle.js"></script>
<div>
<div ng-app="sampleApp" ng-controller="MainCtrl">
<ion-content style="display:block">
<form ng-submit="addResource()">
<div class="list list-inset" ng-repeat="test in tests">
<ion-radio ng-model="settings.id" ng-value="test.id">{{test.id}}</ion-radio>
</div>
<br/>
<div class="list" style="margin: 5px 10px;">
<label class="item item-input item-stacked-label"> <span class="input-label">Email</span>
<input type="text" ng-model="settings.email">
</label>
</div>
<button class="button button-positive">Save</button>
</form>
</ion-content>
</div>
</div>