Add to list functionality in angular - javascript

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 = "";
}
})

Related

Unable to get property 'subject' of undefined or null reference

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 = {};

ng-model doesnt bind with text field

Consider the following JS
angular.module('myApp')
.controller('HeaderCtrl', function($scope) {
$scope.searchBooking = "test";
$scope.goToBooking = function() {
console.log($scope.searchBooking);
//$location.path('/bookings/' + $scope.searchBooking);
//delete($scope.searchBooking);
}
$scope.printValue = function() {
console.log($scope.searchBooking);
}
}
);
And the following HTML
<div class="input-group custom-search-form">
<input type="text" class="form-control" placeholder="Testing" ng-model="searchBooking" ng-change="printValue()">
<span class="input-group-btn">
<button class="btn btn-default" type="button">
<i class="fa fa-search"></i>
</button>
</span>
</div>
My problem is that when the page loads, "test" is written in the text field, but when I change the field or press the button, nothing happens (console says "test" on every change or button click. Anyone know what I did wrong?
Try to wrap the value in an object. Objects are passed by reference, but simple values are passed as a copy of that value. It happened to me too several times.
Try this approach
$scope.myObject.searchBooking = "test"
So the full code will look like this
angular.module('myApp')
.controller('HeaderCtrl', function($scope) {
$scope.myObject.searchBooking = "test";
$scope.goToBooking = function() {
console.log($scope.myObject.searchBooking);
//$location.path('/bookings/' + $scope.myObject.searchBooking);
//delete($scope.myObject.searchBooking);
}
$scope.printValue = function() {
console.log($scope.myObject.searchBooking);
}
}
);
and the html
<input type="text" class="form-control" placeholder="Testing" ng-model="myObject.searchBooking" ng-change="printValue()">
Find this fiddle which is having ng-model binding in ng-change.
HTML
<div ng-controller="MyCtrl">
<div class="input-group custom-search-form">
<input type="text" class="form-control" placeholder="Testing" ng-model="searchBooking" ng-change="printValue()">
<span class="input-group-btn">
<button class="btn btn-default" type="button">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</div>
Angular controller
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.searchBooking = "test";
$scope.goToBooking = function() {
console.log($scope.searchBooking);
//$location.path('/bookings/' + $scope.searchBooking);
//delete($scope.searchBooking);
}
$scope.printValue = function() {
console.log($scope.searchBooking);
}
}

reseting input field after entering data

i have one input box, and im working with scanner that automatic inputs numbers when scans something, now i want to automatically assign that value to some variable, and delete it so it can get another input, any ideas?
html
<ion-view hide-nav-bar="true">
<ion-content class="padding"><br>
<label class="item item-input">
<input type="number" ng-model="code" id="code" name="theInput" auto-focus>
</label>
<div class="tt"><br><br>
Code : <span class="art">{{code}}<br><br></span>
</div><br>
<button ng-click="clear(code)" class="button button-positive">
Clear
</button>
</ion-content>
</ion-view>
js
.controller('PriCtrl', function($scope) {
window.onload = function() {
document.getElementById("code").focus();
};
$scope.clear= function(code){
$scope.val = code;
document.getElementById("code").value = '';
}
just one line change
$scope.clear= function(code){
$scope.val = code;
$scope.code = ''; //ng-model of input is code
}
you should read about how angular data binding is working
If a variable is in the scope the view can access it. if you modify the variable value the in the controller side the view will be updated automatically and vice versa.
You should avoid using jQuery as much as you can and manipulating DOM from controller like this :
`document.getElementById("code").value = '';`
is strictly the same as $scope.code = '';
this is a plunker : http://plnkr.co/edit/u3loqpxYIBMX65O9FXGD?p=preview
i will create a array to store the input
js :
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
$scope.selected = [] ;
$scope.code = null ;
$scope.next = function(){
$scope.selected.push( $scope.code );
$scope.code = null
}
});
HTML :
<body ng-controller="MainCtrl">
<ion-view hide-nav-bar="true">
<ion-content class="padding"><br>
<label class="item item-input">
<input type="number" ng-model="code" id="code" name="theInput" auto-focus>
</label>
<div class="tt"><br><br>
Code : <span class="art">{{code}}<br><br></span>
</div><br>
<button ng-click="next()" class="button button-positive">
scan next
</button>
</ion-content>
</ion-view>
<pre>{{selected|json}}</pre>
</body>
In Angular, try to never do something like this document.getElementById("code").value = '';.
You could simply watch the code variable for changes, and if it gets a new value, you copy it over into a values list and then delete the value from code.
.controller('PriCtrl', function($scope) {
$scope.$watch('code', function(newVal, oldVal) {
if (newVal != '') {
$scope.codelist.push(newVal);
$scope.code = '';
}
});
}

$apply in angularJs not updating my scope variables

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;
}
};
}

Controller and input form html use var Javascript

I use the angularjs framework, I created an form.html and a controller.js with a variable that retrieves the SSID of a box.
How to automatically assign the value of the variable in the form.
This is an input field.
When launching the application, the form should display the SSID automatically without the user needing to do so.
Thank you kindly help me.
'use strict';
angular.module('djoro.controllers')
.controller('WifiSmartConfigCtrl', function ($scope, $window, $ionicPlatform) {
$scope.getSSID = function () {
var onSuccess = function (SSID) {
document.write(SSID);
};
var onFail = function () {
};
$ionicPlatform.ready(function () {
$window.cordova.plugins.Smartconfig.getSSID(onSuccess, onFail);
});
};
});
<ion-pane>
<ion-content ng-controller="WifiSmartConfigCtrl">
<form novalidate class="simple-form">
<fieldset>
<legend>WI-FI</legend>
<div class="list input-fields">
<label class="item item-input">
<span class="input-label">SSID :</span>
<input type="text" name="test" value="getSSID()" required show-hide-input>
</label>
<label class="item item-input" show-hide-container>
<span class="input-label">Password :</span>
<input type="text" name="password" required show-hide-input>
</label>
</div>
</fieldset>
</form>
</ion-content>
</ion-pane>
use the ng-model directive, it's exactly it's purpose :
'use strict';
angular.module('djoro.controllers')
.controller('WifiSmartConfigCtrl', function($scope, $window, $ionicPlatform) {
$scope.SSID = {};
$scope.getSSID = function() {
var onSuccess = function(SSID) {
$scope.SSID = SSID;
};
var onFail = function() {};
$ionicPlatform.ready(function() {
$window.cordova.plugins.Smartconfig.getSSID(onSuccess, onFail);
});
};
});
and in your view :
<input type="text" name="test" ng-model="SSID" required show-hide-input>
You need to add an ng-model to the input field like so:
<label class="item item-input">
<span class="input-label">SSID :</span>
<input type="text" name="test" ng-model="SSID" required show-hide-input>
</label>
then in your controller assign the value of SSID on the $scope:
$scope.SSID = [some_value]
see this plnkr
As you can see I have assigned the value of SSID manually, you can add it dynamically by assigning it in the callback of your function like so:
$scope.SSID = {}
var onSuccess = function (SSID) {
document.write(SSID);
$scope.SSID = SSID
};

Categories