How to display one record from firebase in html? - javascript

I am trying to display one single record in HTML from firebase query, what am I doing wrong? This is the controller:
function getUrlVars()
{
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi,
function (m, key, value) { vars[key] = value; });
return vars;
}
var first = getUrlVars()["id"];
console.log("The id is: " + first);
$scope.username = CommonProp.getUser();
if (!$scope.username) {
$location.path('/home');
}
var firebaseObj = new Firebase("https://crackling-inferno-2072.firebaseio.com/Articles/" + first);
var sync = $firebase(firebaseObj.startAt($scope.username).endAt($scope.username));
$scope.title = sync.$asArray();
$scope.post = sync.$asArray();
console.log($scope.title);
console.log($scope.post);
console.log(sync);
console.log(firebaseObj);
I capture the id form the URL http://localhost:8000/app/#/show?id=-KHNW-LTLsOejTd-cjcO
This is the HTML
<div ng-repeat="article in articles">
<h1>{{title}}</h1>
<p>{{post}}</p>
</div>
<h1 ng-model="article.title">{{article.title}}</h1>
<p>{{post}}</p>
The issue is that nothing is running, and I need to show the title and the post from that ID. Can somebody help me out?
Thanks in advance

Related

ReferenceError: lecturerFac is not defined

When I load the html page, my controller retrieves data from an API end point regarding a course. The page gets populate with the data about the course. But at the same time I want to populate part of the page with data about the lecturer of the course (their image, name , description etc ...). I pass the lecturer name to the method using the ng-init directive but I get a
ReferenceError: lecturerFac is not defined.
I am not sure but I believe the issue is the way I am calling the getLecturer() function using the ng-init directive.
What I want to happen when the page loads is have the Lecturer's details displayed on the page along with the course details.
courses.html
<div class="container" ng-controller="CoursesDetailsCtrl">
<div class="row" >
<div class="col-4" ng-model="getLecturer(courses.lecturer)">
<div>
<h3>{{lecturer.name}}</h3>
<<div>
<img class="img-circle" ng-src="{{lecturer.picture}}" alt="" />
</div>
<p>{{lecturer.description}}</p> -->
</div>
</div>
<div class="col-8">
<div class="myContainer" >
<h2>{{courses.name}}</h2>
<div class="thumbnail">
<img ng-src="{{courses.picture}}" alt="" />
</div>
<div>
<p>{{courses.description}}</p>
</div>
</div>
</div>
</div>
</div>
CoursesDetailsCtrl
todoApp.controller('CoursesDetailsCtrl', ['coursesFac','lecturerFac','$scope','$stateParams', function CoursesCtrl(coursesFac, lecturerFac, $scope, $stateParams){
$scope.getLecturer = function(name){
lecturerFac.getLecturerByName(name)
.then(function (response) {
$scope.lecturer = response.data;
console.log($scope.lecturer);
}, function (error) {
$scope.status = 'Unable to load lecturer data: ' + error.message;
console.log($scope.status);
});
};
}]);
lecturerFac
todoApp.factory('lecturerFac', ['$http', function($http) {
var urlBase = '/api/lecturer';
var coursesFac = {};
lecturerFac.getLecturer = function () {
return $http.get(urlBase);
};
lecturerFac.getLecturerByName = function (name) {
return $http.get(urlBase + '/' + name);
};
return lecturerFac;
}]);
todoApp.factory('lecturerFac', ['$http', function($http) {
var urlBase = '/api/lecturer';
var coursesFac = {};
var service = {};
service.getLecturer = function () {
return $http.get(urlBase);
};
service.getLecturerByName = function (name) {
return $http.get(urlBase + '/' + name);
};
return service;
}]);
i Think the cause of this error is the lecturerFac variable is not initialize in the factory. Create an empty object call lecturerFac in the factory and return it.
todoApp.factory('lecturerFac', ['$http', function($http) {
var urlBase = '/api/lecturer';
var coursesFac = {};
var lecturerFac= {};/////////////////////
lecturerFac.getLecturer = function() {
return $http.get(urlBase);
};
lecturerFac.getLecturerByName = function(name) {
return $http.get(urlBase + '/' + name);
};
return lecturerFac;
}]);
Also avoid calling functions inside the ng-model. When you bind something with ng-model it must be available for both reading and writing - e.g. a property/field on an object. use ng init instead

angularjs calling outer controller from nested ng controllers with ng-change

I'm trying to use angularjs to create a page that does the following:
Is initially empty, save for a dropdownlist that is automatically
populated with apps.
upon selecting one of those apps, data about it will be called from
another controller to the page.
I was successfully able to get the dropdownlist to automatically populate. however, I'm having issues getting it to make the page with ng-change, which I thing is due to the nested ng-controllers. The chartappsuccessfullogins function is not being called at all in my browser. Can anyone help me? Code is below:
My main html page. Note the use of ng-init:
<div ng-controller="chartsuccessfulapploginsController">
<div ng-controller="allappsController" ng-init="add()">
<form name="myForm">
<label for="repeatSelect"> Repeat select: </label>
<select name="repeatSelect" id="repeatSelect" ng-model="data.repeatSelect" ng-change="chartsuccessfulapploginsController.add(value)">
<option ng-repeat="option in data.availableOptions" ng-init="Index = $index" value="{{data.availableOptions[Index].id}}" ng-model="APPID" >{{data.availableOptions[Index].name}}</option>
</select>
</form>
<hr>
<p> {{data}}</p>
<p> {{data.id[0]}}</p>
<p> {{data.name[0]}}</p>
<tt>repeatSelect = {{data.repeatSelect}}</tt><br/>
</div>
<p>{{returnCount}}</p>
<table border = "1">
<tr>
<td>{{chartObject.data}}</td>
<td>{{returnCount}}</td>
</tr>
</table>
<div google-chart chart="chartObject" style="height:600px; width:100%;"></div>
</div>
My get all apps controller. The html page above relies on this to populate the dropdownlist.
angular.module('scotchApp').controller('allappsController',['$scope', function($scope){
var userurl='';
$scope.add = function(){
userurl = 'http://localhost:8085/rest/uafapp/appslist';
var userdata = {};
var userconfig =
{
headers: {
'Content-Type':'application/json'
}
};
var userPostRequest = $.get(userurl, userdata, userconfig);
var userjson = '{\"USER_DATA_RETRIEVED\" : \"fail\"}';
userPostRequest.done(function(userdata){
userjson = JSON.stringify(userdata);
console.log("userjson :: " + userjson);
var postResponse = jQuery.parseJSON(userjson);
$scope.returnName = postResponse['apps'];
var availableOptionsArray = [];
for(i = 0; i < postResponse['apps'].length; i++){
var availableOptions = {};
availableOptions['id'] = postResponse['apps'][i]['appId'];
availableOptions['name'] = postResponse['apps'][i]['appName'];
availableOptionsArray[i] = availableOptions;
}
var returnData = {};
returnData['repeatSelect'] = null;
returnData['availableOptions'] = availableOptionsArray;
$scope.data = returnData;
console.log($scope.returnData);
$scope.$apply()
});
};
}]);
Part of the controller that defines the chart. It's pretty long, so I didn't include the irrelevant code.
angular.module('scotchApp').controller('chartsuccessfulapploginsController',['$scope','$route','$http','AuthTokenService', function($scope, $route, $http, AuthTokenService){
var appurl = '';
var failedappurl= '';
$scope.add = function(APPID) {
...}
Is your allappsController within your chartsuccessfulapploginsController in your controller file?
It should be inside because allappsController is the child scope, and chartsuccessfulapploginsController is the parent scope. You are trying to access the parent scope from the child scope.
If it is not inside, it thinks that ng-change="chartsuccessfulapploginsController.add(value)" is a new controller.
If that is the issue, the fix would be something like this:
angular.module('scotchApp').controller('chartsuccessfulapploginsController',['$scope','$route','$http','AuthTokenService', function($scope, $route, $http, AuthTokenService){
var appurl = '';
var failedappurl= '';
$scope.add = function(APPID) {} ...
//allappsController inside chartsuccessfulapploginsController
angular.module('scotchApp').controller('allappsController',['$scope',function($scope){
var userurl='';
$scope.add = function(){ ... };
}]);
}]);
Check this out: Use ng-model in nested Angularjs controller

Getting value from JSON object with Angular

I've been trying to learn AngularJS recently, and hit a bump in the road with Localstorage i spend so many hours trying to make it save locally, I think that it's working as it should now, but now i would like to print out the data saved local from the JSON array, how can i go about that?
EDIT:
A bit of clarification, What im trying to achieve is getting the information i save in the localstorage out onto the website as a string, so it's readable. hope i'ts more understandable. Thanks in advance
My view.
<ion-list>
<div >
<ion-item ng-controller='ModalEditCtrl' ng-click="openModal()">
<div class="thumbnail" style="border:1px black solid">
</div>
<div ng-controller="createPerson" class="contactinfo" >
<li ng-repeat="contact in contactdetail.contactinfo"> {{contact.name}} </li>
</div>
</ion-item>
</div>
<div ng-controller="ModalAddCtrl">
<button type="button" ng-click="openModal()">+++</button>
</div>
</ion-list>
My controller
app.controller('createPerson', function ($scope) {
var id = id_counter = 1;
$scope.editorEnabled = false;
$scope.disableEditor = function() {
$scope.editorEnabled = false;
};
$scope.enableEditor = function() {
$scope.editorEnabled = true;
};
$scope.contactinfo = [
{name: 'test', phone: 1231, email: 'asd#asd.com'}
];
$scope.saveData = function () {
id_counter += 1;
$scope.editorEnabled = false;
$scope.contactinfo.push({
name: $scope.contactName,
phone: $scope.contactPhone,
email: $scope.contactEmail,
sort_id: id_counter
});
//$scope.todoText = ''; //clear the input after adding
localStorage.setItem('contactinfo', JSON.stringify($scope.contactinfo));
// localStorage.setItem("contacts", JSON.stringify(contacts));
}
$scope.loadData = function () {
var contacts = localStorage.getItem("contactinfo");
var contactdetail = JSON.parse(contacts); //
console.log(contactdetail);
}
$scope.clearData = function () {
window.localStorage.clear();
}
});
Your question is not very clear, I dont think you will be able to get much help unless you clean it up a little.
To print out the data (for debugging, usually) you could just add {{contactinfo|json}} somewhere in your html.
To actually display the data for use on the webpage the following should work for you.
<div ng-repeat="contact in contactinfo track by $index">
<div>Name: {{contact.name}}</div>
<div>Phone: {{contact.phone}}</div>
<div>Email: {{contact.email}}</div>
</div>
I think that some of that logic might be better split into a factory, too. Something like this maybe...?
var contactFactory = angular.module('contactFactory', []);
contactFactory.factory('contactInfo', ['$window', function ($window) {
var id = id_counter = 1;
var contacts = [];
function addContact(name, phone, email) {
id_counter += 1;
contacts.push({
name: name,
phone: phone,
email: email,
sort_id: id_counter
});
saveData();
}
function saveData(contactInfo) {
$window.localStorage.setItem('contactinfo', angular.fromJson(contacts));
}
function loadData() {
contacts = angular.toJson($window.localStorage.getItem('contactinfo'));
return contacts;
}
function clearData() {
$window.localStorage.removeItem('contactinfo');
}
return {
addContact: addContact,
saveData: saveData,
loadData: loadData,
clearData: clearData
};
}]);
var app = angular.module('yourAppName', ['contactFactory']);
app.controller('createPerson', ['$scope', 'contactInfo', function ($scope, contactInfo) {
$scope.editorEnabled = false;
$scope.disableEditor = function() {
$scope.editorEnabled = false;
};
$scope.enableEditor = function() {
$scope.editorEnabled = true;
};
$scope.contactinfo = [
{name: 'test', phone: 1231, email: 'asd#asd.com'}
];
$scope.saveData = function () {
contactInfo.addContact($scope.contactName, $scope.contactPhone, $scope.contactEmail);
$scope.editorEnabled = false;
}
$scope.loadData = contactInfo.loadData;
$scope.clearData = contactInfo.clearData;
}]);
Angular has wrapper for window, which should be used inside your code. There is also ngStorage module or many available solutions which are dealing with browser storage in Angular way. Moreover Angular has functions like angular.toJson() and angular.fromJson(). If e.g. jsonObj is JSON array then var obj = angular.fromJson(jsonObj) gives you JavaScript array. If jsonObj has array property inside then you should go with: var jsArray = angular.fromJson(jsonObj).array.

Refresh a ng-repeat list from server every x seconds

As the title suggests I want to be able to refresh a ng-repeat list from the server every 30 seconds or so. More data can be added on the backend, so I want my list to reflect that. Right now I have the regular $http.get( ) working fine which is here:
$scope.select = function() {
$scope.searchText = '';
$scope.selectedItem = null;
var url = 'http:xxxxxxxxxxxx.com';
url += $scope.selectModel.name;
console.debug("GOING TO: " + url);
$http.get(url).success(function(data2) {
$scope.records = [];
data2.forEach(function(r) {
$scope.records.push(r);
});
});
};
and the portion of the web page it supplies is:
<div style="margin: 1em">
<h4>Search</h4>
<div role="form">
<!-- start dropdown -->
<div class="form-group">
<select class="form-control" ng-options="model as model.name for model in allModels" ng-model="selectModel" ng-change="select()">
<option value="">Choose Model</option>
</select>
</div>
<!-- /end dropdown-->
<div class="form-group">
<input id="start_date" type="text" class="form-control" placeholder="Threat Date">
</div>
</div>
<div>
<table class="table table-hover table-striped" ng-show="records">
<thead>
<th>#</th>
<th>Name</th>
<th>Score</th>
</thead>
<tr data-ng-repeat=" item in records | orderBy : '-score' | limitTo : 10 " ng-click="moreInfo(item)">
<td>{{$index+1}}</td>
<td>{{item.name.slice(5)}}</td>
<td>{{item.score.toFixed(3)}}</td>
</tr>
</table>
</div>
</div>
Is there a way to choose a time # which the list will refresh? And it has to be without hitting a refresh button or something like that. Thanks in advance.
EDIT This is the error I get when I try and use $interval as suggested:
ReferenceError: $interval is not defined
at Scope.$scope.select (http:xxxxxxxxxx.com/UserQuery/js/script.js:24:7)
at fn (eval at <anonymous> (https://code.angularjs.org/1.4.0-rc.0/angular.js:12822:15), <anonymous>:2:209)
at Scope.$get.Scope.$eval (https://code.angularjs.org/1.4.0-rc.0/angular.js:15465:28)
at https://code.angularjs.org/1.4.0-rc.0/angular.js:21825:13
at https://code.angularjs.org/1.4.0-rc.0/angular.js:24485:9
at forEach (https://code.angularjs.org/1.4.0-rc.0/angular.js:332:20)
at NgModelController.$$writeModelToScope (https://code.angularjs.org/1.4.0-rc.0/angular.js:24483:5)
at writeToModelIfNeeded (https://code.angularjs.org/1.4.0-rc.0/angular.js:24476:14)
at https://code.angularjs.org/1.4.0-rc.0/angular.js:24470:9
at validationDone (https://code.angularjs.org/1.4.0-rc.0/angular.js:24398:9)
SOLUTION With combined efforts from this and another question, I came to a solution. First off, like many on this question mentioned, the key here is the use of $interval. There are a few important things to not about using it though.
It must be included in the dependencies for the controller as
#mcpDESIGNS mentioned.
In my case, where there is a dropdown therefor multiple things I want
to $interval over, it is important to close one when you open a new
one.
$scope.select = function() {
$scope.searchText = '';
$scope.selectedItem = null;
$interval.cancel(mainInterval);
$scope.url = '';
url = 'http:xxxxxxxxxxxxxx.com';
url += $scope.selectModel.name;
console.debug("GOING TO: " + url);
$http.get(url).success(function(data2) {
$scope.records = [];
data2.forEach(function(r) {
$scope.records.push(r);
});
});
mainInterval = $interval(function() {
console.debug("UPDATING....");
console.debug("GETTING NEW FROM " + url);
$http.get(url).success(function(data2) {
$scope.records = [];
data2.forEach(function(r) {
$scope.records.push(r);
});
});
}, 5000);
};
Have a look at this:
https://docs.angularjs.org/api/ng/service/$interval
It wraps JavaScript's native setInterval function. You can set it to do the poll every 30 seconds.
It also returns a promise so you can cancel the interval when required.
However, please bear this in mind:
"Intervals created by this service must be explicitly destroyed when you are finished with them. In particular they are not automatically destroyed when a controller's scope or a directive's element are destroyed. You should take this into consideration and make sure to always cancel the interval at the appropriate moment. See the example below for more details on how and when to do this."
EDIT
Taking your code:
$scope.select = function() {
$scope.searchText = '';
$scope.selectedItem = null;
var url = 'http:xxxxxxxxxxxx.com';
url += $scope.selectModel.name;
console.debug("GOING TO: " + url);
$http.get(url).success(function(data2) {
$scope.records = [];
data2.forEach(function(r) {
$scope.records.push(r);
});
});
};
Try changing to this:
$scope.select = function() {
$scope.searchText = '';
$scope.selectedItem = null;
var url = 'http:xxxxxxxxxxxx.com';
url += $scope.selectModel.name;
console.debug("GOING TO: " + url);
$http.get(url).success(function(data2) {
$scope.records = [];
data2.forEach(function(r) {
$scope.records.push(r);
});
});
$interval(function() {
$http.get(url).success(function(data2) {
$scope.records = [];
data2.forEach(function(r) {
$scope.records.push(r);
});
});
}, 30000);
};
If that works you can then refactor the actual $http.get out into a named function to remove the code smell.
Just use a $interval() around your $http to make it refresh every 30 seconds.
$interval(function () {
$http({
/* run your AJAX and update your $scope / etc */
});
}, 30000); // in milliseconds
Note: $interval must be dependency injected into your controller / service / etc to work!
// for examples sake
.controller('MyController', ['$interval', function ($interval) { }]);
Use ng-table instead.
Have a look http://bazalt-cms.com/ng-table/
And u can call its reload propery, which will refresh your table,
The reload you can call inside $timeout service provided by angular.
$timeout(function(){
tablename.reload();
},3000);
or
Just call the select function inside the timeout
$timeout(function(){
$scope.select();
},3000);
Try this:
Ok, I think the plan is each time select is fired, the existing interval needs to be cancelled and another one started. Have a look at this:
var intervalObj;
$scope.select = function() {
if (intervalObj !== null) {
$interval.cancel(intervalObj);
intervalObj = null;
}
$scope.searchText = '';
$scope.selectedItem = null;
var url = 'http:xxxxxxxxxxxx.com';
url += $scope.selectModel.name;
console.debug("GOING TO: " + url);
$http.get(url).success(function(data2) {
$scope.records = [];
data2.forEach(function(r) {
$scope.records.push(r);
});
});
intervalObj = $interval(function() {
$http.get(url).success(function(data2) {
$scope.records = [];
data2.forEach(function(r) {
$scope.records.push(r);
});
});
}, 30000);
};
I have not been able to fully test this, but the principle is sound.

How to create a custom JSON based on form values?

I am creating a JSON based on a dynamic form values below, when the user submits, i am displaying the json feed in #results
Is it also possible to get all the values in the form when generating the JSON, I want to get the
name, ids,
title information,
input value etc
and then create/display the JSON in the order below?
A working version can viewed here :
http://jsfiddle.net/dev1212/GP2Y6/25/
Currently its not retuning any values and getting some undefined..
the code peice i tried is below
<script>
x = function(selector){
var attrs = [];
$(selector + " input").each(function(){
var attrObject = {};
$(this.attributes).each(function(index, attr){
attrObject[attr.name] = attr.value;
attrObject[attr.va] = attr.value;
//console.log(attrObject)
});
attrs.push(attrObject);
attrObject = {};
});
return attrs;
}
$(document).ready(function(){
alert(JSON.stringify(x("#myform")));
});
</script>
<script type="text/javascript" src="/www/include/js/jquery.min.js"></script>
<script>
x = function(selector){
var attrs = [];
$(selector + " input").each(function(){
var attrObject = {};
$(this.attributes).each(function(index, attr){
attrObject[attr.name] = attr.value;
//console.log(attrObject)
});
attrs.push(attrObject);
attrObject = {};
});
return attrs;
}
$(document).ready(function(){
alert(JSON.stringify(x("#myForm")));
});
</script>
<form id="myform" class="form-wd">
<input class="ui-dform-text" type="text" title="data for network.node1.eth0.ipaddr" name="network.node1.eth0.ipaddr">
</form>

Categories

Resources