Foreach with firebase - angularjs

var myApp = angular.module("myApp", ["firebase"]);
var nick = prompt("Anna nimesi");
myApp.controller("MyController", ["$scope", "$firebaseArray",
function($scope, $firebaseArray) {
var msgref = new Firebase("https://(myapp).firebaseio.com/messages");
var usrref = new Firebase("https://(myapp).firebaseio.com/users");
$scope.messages = $firebaseArray(msgref);
$scope.users = $firebaseArray(usrref);
console.log($scope.users);
console.log($scope.messages);
var taken = false;
angular.forEach($scope.users, function(value, key) {
console.log(value, key);
if (value.username == nick) {
taken = true;
}
// put your code here
});
if (taken == false) {
$scope.users.$add({
username: nick
});
};
$scope.addMessage = function(e) {
if (e.keyCode == 13 && $scope.msg) {
var name = nick || "anynomous";
$scope.messages.$add({
from: name,
body: $scope.msg
});
$scope.msg = "";
}
}
}
])
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />
<title>title</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://cdn.firebase.com/js/client/2.2.4/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/angularfire/1.1.1/angularfire.min.js"></script>
</head>
<body ng-controller="MyController">
<div class="example-chat l-demo-container">
<ul id="example-messages" class="example-chat-messages">
<li ng-repeat="msg in messages">
<strong class="example-chat-username">{{msg.from}}</strong>
{{msg.body}}
</li>
</ul>
</div>
<input class="input" autofocus="true" ng-model="msg" ng-keydown="addMessage($event)" type="text" id="messageInput" placeholder="kirjota">
<script src="script.js"></script>
</body>
</html>
Im doing a chat, and i want to check if there is already a user with same name, so that there could not be two users with same nick. This does not work, and i can add many same nicks.
var usrref = new Firebase("https://(myapp).firebaseio.com/users");
$scope.users = $firebaseArray(usrref);
var taken = false;
for (var usr in $scope.users) {
if(usr.username == nick){
taken = true;
};};
if(taken == false){
$scope.users.$add({username:nick});
};
My messages is showing perfectly with ng-repeat in html, but i cant get this work. Its obviously something simple, but i have struggled too long with this.

Since you're using Angular, I'd suggest using Angular's forEach method. Here's an example of what you could do:
angular.forEach($scope.users, function(value, key) {
// put your code here
});
Edited
This should work for you. It checks your data after it has been loaded from Firebase. If the username is present, then it doesn't add the name. If it is not present, then it's added. You could check out the AngularFire API for $loaded().
var addNameToArray = true;
$scope.users.$loaded().then(function(data) {
angular.forEach(data, function(value, key) {
if(value.username === "John") {
addNameToArray = false;
}
});
if(addNameToArray) {
$scope.users.$add({username: "John"});
}
});

A for (var ... in ...) iterates over object keys. So if $scope.users is an array you'll get indexes: 0, 1, 2, ... in the usr variable. To iterate over an array you can use for example following construct:
$scope.users.forEach(function(user) {
});
But maybe instead of using an array it would be better to use an object indexed by username. Then you'll get immediate information if given user exists (users[nick] !== undefined) and you'll also avoid some other trouble. See Best Practices: Arrays in Firebase.

Related

AngularJs with REST Api

i'm new to angularJs and want to learn more about it, i'm trying to display some users from a fake REST Api, when trying to run my code i got empty page and the console doesn't give me any errors , i don't know where is the error or where i can debug.
app.js
var myApp = angular.module("app", []);
contactsData.service.js look like that :
(function () {
var app = angular.module("app");
app.service("contactDataSvc", function ($http) {
var self = this;
self.getContacts = function () {
var promise1 = $http.get("http://localhost:3000/contacts");
var promise2 = promise1.then(function (response) {
return response.data;
});
return promise2;
}
});
})();
contacts.controller.js
(function () {
var myApp = angular.module("app");
myApp.controller("contactsCtrl", contactsCtrl);
function contactsCtrl(contactDataSvc) {
contactDataSvc.getContacts()
.then(function(data){
this.contacts = data;
});
}
})();
finally my view index.html
<html ng-app="app">
<head>
<title></title>
<script src="angular.js"></script>
<script src="app.js"></script>
<script src="contacts.controller.js"></script>
<script src="contactsData.service.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" />
<!--<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>-->
</head>
<body class="container">
<div>
<div ng-controller="contactsCtrl as ctrl">
<div class="raw">
<ul class="list-group">
<li class="li-group-item" ng-repeat="obj in ctrl.contacts">
{{obj.name.title + " " + obj.name.first + " " + obj.name.last}}
</li>
</ul>
</div>
</div>
</div>
</body>
</html>
Small correction required in your contactsCtrl
function contactsCtrl(contactDataSvc) {
var vm = this;
contactDataSvc.getContacts()
.then(function(data){
vm.contacts = data;
});
}
You cannot use this inside the then callback as the scope will be different.
Corrected working example here : http://plnkr.co/edit/LLKJipkBbiZ17QjQpw1X
Refer more:
https://www.w3schools.com/js/js_scope.asp
What is the scope of variables in JavaScript?
1 - Is this url correct? http://localhost:3000/contacts
2 - Open the url on any browser, does it return any response ? JSON?
Please check this first to see if the problem is not on the server side.
Firstly inject $scope in controller because anything/data that we want to access over Html from controller needs to be binded on $scope.
So you controller would look like:
(function () {
var myApp = angular.module("app");
myApp.controller("contactsCtrl", contactsCtrl);
function contactsCtrl($scope,contactDataSvc) {
contactDataSvc.getContacts()
.then(function(data){
$scope.contacts = data;
});
}
})();
Secondly from the service you need to return a promise from it only then you will be able to get the data once the response is back from the API.
So,the updated service code is :
(function () {
var app = angular.module("app");
app.service("contactDataSvc", function ($http,$q) {
var self = this;
var defered = $q.defer();
self.getContacts = function () {
var promise1 = $http.get("http://localhost:3000/contacts");
promise1.then(function (response) {
defered.resolve(response.data);
});
return defered.promise;
}
});
})();

Split a string in angularjs controller

I am trying to split a single string into array or JSON format. Kindly help in doing that in angular js controller (not in HTML view).
The string format is like,
string="Name1;Email1;ID1~Name2;Email2;ID2"
None of the ways I tried worked. I tried using string.split('~') but I am getting an error as split is not a function.
myView.service('ViewService', [function () {
var temp = [];
var fstring = [];
this.SplitUser = function (userstring) {
debugger;
//temp = userstring.split('~');
angular.forEach(userstring, function (value, key) {
fstring.push({
'Name': temp.split(';')[i],
'EmailID': temp.split(';')[i++],
'ID': temp.split(';')[i++]
});
})
console.log(temp);
console.log(fstring);
return temp;
}
Need to loop the temp array.not userstring.Also when you are pushing to the fstring array remove the i and use the position as a number
fstring.push({
'Name': value.split(';')[0],
'EmailID': value.split(';')[1],
'ID': value.split(';')[2]
);
change your service like this.
.service('ViewService', [function () {
var temp = [];
var fstring = [];
this.SplitUser = function (userstring) {
debugger;
temp = userstring.split('~');
angular.forEach(temp, function (value, key) {
fstring.push({
'Name': value.split(';')[0],
'EmailID': value.split(';')[1],
'ID': value.split(';')[2]
});
})
console.log(temp);
console.log(fstring);
return temp;
}
}])
Demo
angular.module("app",[])
.controller("ctrl",function($scope,ViewService){
var string="Name1;Email1;ID1~Name2;Email2;ID2";
ViewService.SplitUser(string)
}).service('ViewService', [function () {
var temp = [];
var fstring = [];
this.SplitUser = function (userstring) {
debugger;
temp = userstring.split('~');
angular.forEach(temp, function (value, key) {
fstring.push({
'Name': value.split(';')[0],
'EmailID': value.split(';')[1],
'ID': value.split(';')[2]
});
})
console.log(temp);
console.log(fstring);
return temp;
}
}])
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
</div>
var string = "Name1;Email1;ID1~Name2;Email2;ID2";
// Initial split in entries
var splitStrings = string.split('~');
var objects = [];
for(var i = 0; i < splitStrings.length; i++) {
// split into properties
var objProps = splitStrings[i].split(';');
var myObj = {};
myObj.name = objProps[0];
myObj.mail = objProps[1];
myObj.id = objProps[2];
objects.push(myObj);
}
console.log(objects);
This should split your string and put it into objects. Then add those objects into an array.
If you want to use JSON and have control over the code that sends you the message I would suggest you use JSON.parse() and JSON.stringify() instead.
This sollution expect a strict structure like the one you posted and has no eror handling.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = [];
var string="Name1;Email1;ID1~Name2;Email2;ID2"
var arr = string.split('~');
angular.forEach(arr, function (value, key) {
$scope.name.push({
'Name': value.split(';')[0],
'EmailID': value.split(';')[1],
'ID': value.split(';')[2]
});
})
console.log($scope.name);
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
</body>
</html>

Angular.js remove item from collections using filter

I need some help with this code, i'm storing "activities" and removing it.
For now it's storing but not removing. (I just need a simple solution to this code).
Angular.js
angular
.module("TodoList",["LocalStorageModule"])
.factory("TodoService", function(localStorageService){
var todoService = {};
todoService.key = "angular-todolist";
if(localStorageService.get(todoService.key)){
todoService.activities = localStorageService.get(todoService.key);
} else {
todoService.activities = [];
}
todoService.add = function(newActv){
todoService.activities.push(newActv);
todoService.updaLocalStorage();
};
todoService.updaLocalStorage = function(){
localStorageService.set(todoService.key, todoService.activities);
};
todoService.clean = function(){
todoService.activities = [];
todoService.updaLocalStorage();
};
todoService.getAll = function(){
return todoService.activities;
};
toDoService.removeItem = function (item) { **Creating function for remove**
toDoService.activities = toDoService.activities.filter(function (activity) {
return activity !== item;
});
toDoService.updateLocalStorage();
return toDoService.getAll();
};
return toDoService;
})
.controller("TodoListCtrl", function($scope, todoService){
$scope.todo = todoService.getAll();
$scope.newActv = {};
$scope.addActv = function(){
todoService.add($scope.newActv);
$scope.newActv = {};
}
$scope.removeActv = function (item) { **Scope for remove**
$scope.todo = ToDoService.removeItem(item);
}
$scope.clean = function(){
todoService.clean();
}
});
Html
<!DOCTYPE html>
<html ng-app = "TodoList">
<head>
<meta charset="utf-8">
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.2/angular.min.js"></script>
<script src = "todoctrl.js"></script>
<script src = "angular-local-storage.min.js"></script>
</head>
<body ng-controller = "TodoListCtrl">
<ul>
<li ng-repeat = "actividad in todo">
{{actividad.descripcion}} -
{{actividad.fecha | date: 'short'}} -
x **Where is removing**
</li>
</ul>
<form ng-submit = "addActv()">
<input type="text" ng-model = "newActv.descripcion">
<input type="datetime-local" ng-model = "newActv.fecha">
<input type="submit" value = "Guardar">
</form>
<button ng-click = "clean()">Limpiar</button>
</body>
</html>
update your ToDoService.removeItem(item);function. if you want to remove an item from activity you use array.splice(item) to remove an item from an array. you want to remove an item ToDoService.removeItem(item); function but your function is not doing this. it is returning a value that is either true or false. change your function body.

angular.js ng-hide not working

I am having an issue with using ng-hide. With all of the code below, I am able to get everything working the way I want it to until I add the ng-hide attribute, at which point it refuses to show ANY of the images. If I leave it out, the images all show up like I expect, leaving me to believe my controller is working correctly and I have hooked into it correctly. What am I not understanding? Also, you will see I put an alert in the function to make sure it is being called, but I cannot for the life of me get an alert box to work using angular.
app.js
(function () {
var app = angular.module("mainApp", []);
app.controller("StoriesListController", ["$http", StoriesListController]);
function StoriesListController($http) {
var vm = this;
vm.title = "Tutorial List";
vm.imageIndex = 0;
activate();
function activate() {
vm.stories = [];
$http.get("api/Story").then(function (response) {
vm.stories = response.data;
});
}
vm.setCurrentImage = function (index) {
vm.imageIndex = index;
};
vm.isCurrentImage = function (index) {
alert(index);
return vm.imageIndex === index;
};
}
}());
index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="mainApp">
<head>
<title>TEST</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="/Scripts/bootstrap.min.js"></script>
<script src="Scripts/angular.min.js"></script>
<script type="text/javascript" src="Scripts/App.js"></script>
<link href="/Content/bootstrap.min.css" type="text/css" rel="stylesheet" />
</head>
<body>
<h1>TEST</h1>
<div ng-controller="StoriesListController as vm">
<h1>{{vm.title}}</h1>
<div class="container slider">
<div ng-repeat="story in vm.stories">
<img ng-src="{{story.PreviewImageURL}}" ng-hide="!isCurrentImage($index)" class="slide" />
</div>
</div>
</div>
</body>
</html>
StoryController.cs (the API I am calling to fill stories)
namespace AngularWebApi.Controllers
{
public class StoryController : ApiController
{
private static readonly List<Story> apps = new List<Story>
{
new Story
{
ID = 1,
Name = "Test 1",
Descript = "Test 1 Desc",
PreviewImageURL = "/Images/Test1.png",
Views = 1,
Ranking = 1
},
new Story
{
ID = 2,
Name = "Test 2",
Descript = "Test 2 Desc",
PreviewImageURL = "/Images/Test2.png",
Views = 1,
Ranking = 2
},
new Story
{
ID = 3,
Name = "Test 3",
Descript = "Test 3 Desc",
PreviewImageURL = "/Images/Test3.png",
Views = 1,
Ranking = 3
},
};
public IHttpActionResult Get()
{
return Ok(apps);
}
}
}
I think you just miss vm. Try ng-hide="!vm.isCurrentImage($index)".

How does service variable change update to controllers

I have a small problem and I don't understand this thing:
When I add an item to TestiFactorys arr - array it does update to both controllers
On the other hand why does not TestiFactorys arr_len update to both controllers. And in TestiController why do I have to "manually" update TestControllers list1_length to make it update to view but I don't have to update TestiContollers list1 to make it update to view
I am assuming that my poor Javascript or Javascript variable scope understanding is causing this but i just don't see it.
I am using AngularJS version 1.2.16
<!DOCTYPE html>
<html ng-app="TestiApp">
<head>
<title></title>
</head>
<body>
<div ng-controller="TestController">
List items from controller: {{list1}}<br>
List item count:{{list1_length}}
<input type="text" ng-model="param"><br>
<button ng-click="list1_add(param)">asd</button>
</div>
<br><br>
<div ng-controller="TestController2">
List items from controller2{{list2}} <br>
List items count in from controller2: {{list2_length}}
</div>
<script src="scripts/angular.min.js"></script>
<script src="scripts/app.js"></script>
</body>
</html>
And this is my app.js:
var TestiApp = angular.module('TestiApp', [])
TestiApp.factory('TestiFactory',function() {
var arr = ['abx','cbs'];
var arr_len = arr.length;
return {
list : function() {
return arr;
},
add_to_arr : function(n) {
arr.push(n);
},
arr_len : function() {
arr_len = arr.length;
return arr_len;
}
}
}
);
TestiApp.controller('TestController', function($scope, TestiFactory) {
$scope.list1 = TestiFactory.list();
$scope.list1_length = TestiFactory.arr_len();
$scope.list1_add = function (d) {
TestiFactory.add_to_arr(d);
$scope.param = '';
$scope.list1_length = TestiFactory.arr_len();
}
});
TestiApp.controller('TestController2', function($scope, TestiFactory) {
$scope.list2 = TestiFactory.list();
$scope.list2_length = TestiFactory.arr_len();
});
EDIT WITH SOLUTION
Here is working solution. Based to comments I decided to do more studying on Javascripts basics which
is of course the thing I should have done before trying to use this complex framework which uses Javascript. So now I have some basic understanding how to use references in Javascript and what primitive data types are. And based on that here is working version:
<!DOCTYPE html>
<html ng-app="TestiApp">
<head>
<title></title>
</head>
<body>
<div ng-controller="TestController">
List items from controller: {{list1()}}<br>
List item count:{{list1_len()}}
<input type="text" ng-model="param"><br>
<button ng-click="list1_add(param)">asd</button>
</div>
<br><br>
<div ng-controller="TestController2">
List items from controller2{{list2()}} <br>
List items count in from controller2: {{list2_length()}}
</div>
<script src="scripts/angular.min.js"></script>
<script src="scripts/app.js"></script>
</body>
</html>
And app.js:
var TestiApp = angular.module('TestiApp', [])
TestiApp.factory('TestiFactory',function() {
var arr = ['abx','cbs'];
return {
list : function() {
return arr;
},
add_to_arr : function(n) {
arr.push(n);
},
arr_len : function() {
return arr.length;
}
}
}
);
TestiApp.controller('TestController', function($scope, TestiFactory) {
$scope.list1 = TestiFactory.list;
$scope.list1_add = TestiFactory.add_to_arr;
$scope.list1_len = TestiFactory.arr_len;
});
TestiApp.controller('TestController2', function($scope, TestiFactory) {
$scope.list2 = TestiFactory.list;
$scope.list2_length = TestiFactory.arr_len;
});
I've ran into this many times. Factories and services in angular are not like scopes...they work using references. The reason the array updates in your controllers is because the original reference was updated. The length is not updating because the number type is primitive.
This should work:
TestiApp.controller('TestController', function($scope, TestiFactory) {
$scope.list1 = TestiFactory.list();
$scope.$watch('list1', function(list1) {
$scope.list1_length = list1.length;
});
$scope.list1_add = function (d) {
TestiFactory.add_to_arr(d);
$scope.param = '';
};
});
TestiApp.controller('TestController2', function($scope, TestiFactory) {
$scope.list2 = TestiFactory.list();
$scope.$watch('list2', function(list2) {
$scope.list2_length = list2.length;
});
});

Resources