I've been attempting to make my virgin query with JavaScript from a Parse database. I'd like to take data from a Parse column (named primary) and display it on the front end on a drop down. I've tried a large number of combinations but as of now I'm unable to make much progress. My Angular controller:
angular.module('startupApp')
.controller('bizOfferCtrl', function ($scope, $http) {
var primary = new Parse.Query(bizCategories);
$scope.getPrimary = function() {
$scope.bizCategories.relation("primary").query().find({
success: function(list) {
$scope.bizCategories.primary = list;
}
});
};
And the html (with bootstrap and SCSS) that goes along with that:
<div class="btn-group col-xs-4 col-sm-4 col-md-4 col col-lg-4" dropdown is-open="status.isopen">
<button type="button" class="btn btn-primary" dropdown-toggle>
{{getPrimary()}} <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" >
<li ng-repeat="category in bizCategories.primary">
{{category.primary}}
</li>
</ul>
</div>
You're not providing an error callback for the query, which could be used to provide insight into why your query is failing. See here.
You're also calling query().find() but you defined and bound the query to primary and Parse.Query is not a function, but an object. Try
primary.find({
success: function(list) {
$scope.bizCategories.primary = list;
}, error: function(error) {
// handle error
}
});
Also, I don't know if chaining the function call in the way you did is valid either, but I don't use Angular JS so I can't speak to the validity of this. From my perspective, it looks like you're trying to access it as a property of all of that.
Related
The view in my html is not getting filtered on selecting any li element.
But when I console the filter functions the output generated is correct.Also how to clear the filter so it is reusable again.I'm getting a blank page on clicking open or close select elements.Can anyone help me with this.
I have used two filters in a controller inside the functions like this-
indexController Functions-
this.UserTickets = ()=> {
//code to get the tickets
}
this.openTickets = () => {
index.filteredTickets = $filter('filter')(index.tickets, { status: "open" } );
console.log(index.filteredTickets);
};
//filter closed tickets
this.closeTickets = () => {
index.filteredTickets = $filter('filter')(index.tickets, { status: "close" } );
console.log(index.filteredTickets);
};
this.clearFilter = () => {
//clear the filter
};
HTML-
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a ng-click="indexCtrl.clearfilter()">None</a></li>
<li><a ng-click="indexCtrl.openTickets()">Open</a></li>
<li><a ng-click="indexCtrl.closeTickets()">Close</a></li>
</ul>
<div ng-repeat="ticket in indexCtrl.tickets | filter:tickets |filter:indexCtrl.filteredTickets">
<div class="ticket-no">
<h4>Ticket No:<span>{{ticket}}</span></h4>
</div>
<div class="ticket-title">
<a ng-href="/ticketView/{{ticket.ticketid}}"><h3>{{ticket.title}}</h3></a>
</div>
<div class="ticket-info">
<p class="pull-left">{{ticket.username}} On {{ticket.created | date:"MMM d, y h:mm a"}}</p>
<p class="pull-right">Status:<span>{{ticket.status}}</span></p>
</div>
<hr class="hr">
</div>
You are mixing both angular filter options. I would recommend the javascript filters, index.filteredTickets=$filter('filter')(index.tickets,{status:"open"}); rather than the html template syntax, ng-repeat="ticket in indexCtrl.tickets | filter:tickets...". The key difference between these methods is how often they are run. The html template syntax filters are run on every digest cycle, the javascript filters are only run when the method is called, in your case, on each button click. For small apps or when the lists are small, this difference won't be noticeable, but if your app grows in size, the constant filtering on each digest cycle can cause page lag.
The filters in the controller are my preferred way of handling this, so I will show you how to clean up your code for these to work. You are almost there, just a few small changes are needed.
In your html, you can remove the inline filters in the ng-repeat, these aren't needed, and change the array to be your filter list, index.filteredTickets.
.html
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a ng-click="indexCtrl.clearfilter()">None</a></li>
<li><a ng-click="indexCtrl.openTickets()">Open</a></li>
<li><a ng-click="indexCtrl.closeTickets()">Close</a></li>
</ul>
<div ng-repeat="ticket in indexCtrl.filteredTickets">
<div class="ticket-no">
<h4>Ticket No:<span>{{ticket}}</span></h4>
</div>
<div class="ticket-title">
<a ng-href="/ticketView/{{ticket.ticketid}}"><h3>{{ticket.title}}</h3></a>
</div>
<div class="ticket-info">
<p class="pull-left">{{ticket.username}} On {{ticket.created | date:"MMM d, y h:mm a"}}</p>
<p class="pull-right">Status:<span>{{ticket.status}}</span></p>
</div>
<hr class="hr">
</div>
For the javascript, you need to make sure the filteredTickets are accessible in the html. I'm not sure if index == this, if not, you may need to attach the filtered tickets to the scope. The one other change needed is to set the filteredTickets to your original list if the none button is pressed. You will also want to call clearFilter after you load the list, otherwise index.filteredList will be undefined/null.
.js
this.UserTickets = () => {
//code to get the tickets
....
//after getting list, call clear filter
this.clearFilter();
}
this.openTickets = () => {
index.filteredTickets = $filter('filter')(index.tickets, { status: "open" } );
console.log(index.filteredTickets);
};
//filter closed tickets
this.closeTickets = () => {
index.filteredTickets = $filter('filter')(index.tickets, { status: "close" } );
console.log(index.filteredTickets);
};
this.clearFilter = () => {
//clear the filter
index.filteredTickets = index.tickets;
};
My data in Firebase looks like this...
evalu8er
situations
-K6rM12D-0nt4fJH_QcA
situation: "Test"
-K6rPoHiUl2N2JOSWXww
situation: "Test2"
-K6rPqbkBHJ-K8znVzay
situation: "Test3"
I have inserted the data from an HTML page via a form like this...
<div class="form-group">
<label for="situation">Add a situation</label>
<input type="text" class="form-control" id="situation" placeholder="Situation" ng-model="situation">
</div>
<button type="submit" class="btn btn-default pull-right" ng-click="add_situation()"><i class="fa fa-cog fa-spin" ng-show="loading"></i> Add </button>
</form>
The above form is calling the controller...
app.controller("situations", ["$scope", function ($scope) {
$scope.add_situation = function () {
var situation = $scope.situation;
var ref = new Firebase("https://evalu8er.firebaseio.com/situations");
ref.push().set({
situation: situation
});
};
}
]);
Now I want to get each of the situations back to the page, and this where it all goes wrong for me.
Inside the same controller as above I'm adding this....
var ref = new Firebase("https://evalu8er.firebaseio.com/user/situations/");
ref.on("value", function(snapshot) {
$scope.display_situatoins = snapshot.val();
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
And on the HTML page I have added
<li data-ng-repeat="x in display_situatoins">
{{ x }}
</li>
When the page loads it DOES NOT show me the data until I enter something in the form field,
Question 1/3)
How do I get the data to show on page load?
When it does load it looks like this...
{"situation":"Test"}
{"situation":"Test2"}
{"situation":"Test3"}
And what I want is just to show a list of the situations like this..
Test
Test2
Test3
Question 2/3)
How do I just show the situation values as above?
And when I do add a new item it gets listed at the bottom, how do I order the list with the new items at the top?
Question 3/3)
How do I order the list so the new items appear first?
Use AngularFire for synchronized collections.
angular.module('app', ['firebase'])
.constant('FirebaseUrl', '<my-firebase-app>')
.service('rootRef', ['FirebaseUrl', Firebase])
.controller('MyCtrl', MyController);
function MyCtrl($scope, rootRef, $firebaseArray) {
$scope.situations = $firebaseArray(rootRef.child('situations');
}
Then in your template for MyCtrl, you can do an ng-repeat on the situations array.
<li ng-repeat="situation in situations">
{{ situation.situation }}
</li>
The {{ situation.situation }} part looks awkward because of the naming. If you change the property situation to something like text or title it would look like:
<li ng-repeat="situation in situations">
{{ situation.title }}
</li>
I am working on a project using angularJS, however I'm a bit unsure of the best way to approach this in the framework.
I have an endpoint that makes a request and searches for some data using some parameters, and upon success, it will loop through the table and return matching items.
For each item I make an HTTP call to get some data and the success response would create the scope that would be used in the markup.
How can I reuse the same HTML in the loop AND set/re-set the scope each time so the markup gets generated for each item...or perhaps theres a better 'angular specific' approach.. Thanks
HTML (this is the markup i would like to reuse)
<div class="carouselWrapperOuter">
<div class="carouselWrapper">
<ul rn-carousel rn-carousel-controls rn-carousel-duration="300" class="image carouselholder">
<li ng-repeat="stuff in homeData" class="square" data-url="{{stuff.id}}" ng-click="trackOpen()">
<div class="squareThumb">
<img ng-src="{{stuff.artwork_url}}">
</div>
<div class="itemTitle">{{stuff.title}}</div>
</li>
</ul>
</div>
</div>
JS
angAppFactory.getUser({
where: {
endpointname: "sourcename",
username: "user123"
}
}).success(function(success) {
console.log(success)
//returns a couple of results which would make the following request AND use the markup/set the scope for each item
for (var i = 0; i < success.results.length; i++) {
var endpointid = success.results[i].sourceid
$http({
method: 'GET',
url: 'http://someurl.com'
}).success(function(data) {
//console.log(data)
//scope being set
$scope.homeData = data;
}).error(function() {
alert("error");
});
}
});
thanks advance for any support. So I have a factory that uses a post to get some data from a C# method. That all seems to be working as I can see the data in the console log when it gets returned. However, when I get the data, I can't seem to get it to display properly using ng-repeat.
I've tried a couple different ways of nesting ng-repeats and still no luck. So now I'm thinking I may have not passed the data from the call properly or my scope is off. I've also tried passing data.d to hangar.ships instead of just data. Still pretty new to angular so in any help to point me int he right direction is greatly appreciated.
app code:
var app = angular.module('shipSelection', ['ngRoute', 'ngResource']);
app.controller('ShipController', function ($scope, ShipService) {
var hangar = this;
hangar.ships = [];
var handleSuccess = function (data, status) {
hangar.ships = data;
console.log(hangar.ships);
};
ShipService.getShips().success(handleSuccess);
});
app.factory('ShipService', function ($http) {
return {
getShips: function () {
return $http({
url: '/ceresdynamics/loadout.aspx/getships',
method: "post",
data: {},
headers: { 'content-type': 'application/json' }
});
}
};
});
Markup:
<div class ="col-lg-12" ng-controller="ShipController as hangar" >
<div class =" row">
<div class="col-lg-4" ><input ng-model="query" type="text"placeholder="Filter by" autofocus> </div>
</div><br />
<div class="row">
<div ng-repeat="ship in hangar.ships | filter:query | orderBy:'name'">
<div class="col-lg-4">
<div class="panel panel-default">
<div>
<ul class="list-group">
<li class="list-group-item" >
<p><strong>ID:</strong> {{ ship.ShipID }} <strong>NAME:</strong> {{ ship.Name }}</p>
<img ng-src="{{ship.ImageFileName}}" width="100%" />
</li>
</ul>
</div>
</div><!--panel-->
</div> <!--ng-repeat-->
</div>
</div>
</div> <!--ng-controller-->
JSON returned from the post(From the console.log(hangar.ships):
Object
d: "[{"ShipID":"RDJ4312","Name":"Relentless","ImageFileName":"Ship2.png"},{"ShipID":"ZLH7754","Name":"Hercules","ImageFileName":"Ship3.png"},{"ShipID":"FER9423","Name":"Illiad","ImageFileName":"Ship4.png"}]"
__proto__: Object
As per AngularJS version 1.2, arrays are not unwrapped anymore (by default) from a Promise (see migration notes). I've seen it working still with Objects, but according to the documentation you should not rely on that either.
Please see this answer Angular.js not displaying array of objects retrieved from $http.get
What happens if you add JSON.parse(data);
If this works you should add some checks in and perhaps migrate that logic to the service. Or use $resource per the other answer.
https://github.com/angular/angular.js/commit/fa6e411da26824a5bae55f37ce7dbb859653276d
In the Ember app I'm building, I've got an ArrayController managing a list of items with several columns of data for each record object in the array with a sort button in each column header in the view. I have set up the list to sort on a given column per Balint Erdi's recommended method here. You will see this sorting in my code below.
The sorting works fine. However, the problem arises when I remove an item from the array. Currently, when I attempt to remove an item from the array, the correct item is apparently removed from the array and is properly deleted from the store and the delete is saved to my backend. However, after the item removal, my view is not correct. In some cases, the wrong item is shown as removed, in other cases, no item is shown as removed. Yet IF I press sort again, the view is updated correctly.
So, the index of the array is obviously getting off some how, but I'm not sure how and all of my attempts to apply the tricks of others are not working!
Here is my route object:
App.UsersFilesRoute = Ember.Route.extend({
model: function () {
return this.modelFor('users').get('files');
}
});
Here is my ArrayController:
App.UsersFilesController = Ember.ArrayController.extend({
sortProperties: ['name'],
sortedFiles: Ember.computed.sort('model', 'sortProperties'),
actions: {
addFile: function(file) {
var newFile = this.store.createRecord('file', {
name: file.name.trim(),
fileSize: file.size,
loaded: false
});
this.pushObject(newFile);
},
sortBy: function (sortProperties) {
this.set('sortProperties', [sortProperties]);
},
removeFile: function (fileToRemove) {
var _this = this;
var file = this.store.find('file', fileToRemove.get('id'));
file.then( function (file) {
_this.removeObject(file);
file.deleteRecord();
file.save();
});
},
saveFile: function (file) {
....
}
}
});
And here is my template code:
<div class="hidden-xs row user-file-header-row">
<div class="col-sm-5 col-md-5 user-file-header">
File Name
<button type="button" class="btn-xs btn-default files-sort-btn" {{ action 'sortBy' 'name'}}></button>
</div>
<div class="col-sm-1 col-md-1 user-file-header">
Size
<button type="button" class="btn-xs btn-default files-sort-btn" {{ action 'sortBy' 'fileSize'}}></button>
</div>
</div>
{{#each file in sortedFiles}}
<div class="row user-file user-file-break">
<div class="col-xs-11 col-sm-5 col-md-5 user-file-name">
<a {{ bind-attr href="file.path" }} >{{ file.name }} </a>
</div>
<div class="col-xs-9 col-sm-1 col-md-1">
{{ format-file-size file.fileSize }}
</div>
<div class="col-xs-9 col-sm-1 col-md-1">
<button type="button" class="btn-xs btn-default files-list-btn" {{ action 'removeFile' file }}></button>
</div>
</div>
{{/each}}
NOTE: There is some similarity between my question and this other StackOverflow question: After using jQuery UI to sort an Ember.js item, using Ember Data's model.deleteRecord() doesn't work, however, I've attempted to apply that answer my own problem with no success. Furthermore, I have no jQuery going on here in my sorting.
OK. I have found an answer, or rather an answer has found me.
My problem was that in the code above I was removing the itemfrom the ArrayController and then calling .delete() and .save(). This sequences of calls was sending conflicting signals to Ember on how to update my view. Apparently, the .removeObject() was actually removing the item from the array, but then the subsequent .delete()/.save() was setting the model behind the view to a state just before deletion (not sure about that but that's what I saw happening).
So anyways, .destroyRecord() returns a promise, so I moved the .removeObject() within the .then() for the promise, and that resolves the issue.
So, the following code in the removeFile action resolved the issue:
removeFile: function () {
var self = this;
var fileToRemove = this.get('fileToRemove');
var file = this.store.find('file', fileToRemove.get('id'));
file.then (function (file) {
file.destroyRecord().then(function(){
self.get('model').removeObject(file);
});
});
}
Note that you don't have to do the this.store.find() first, you could simply do the following:
removeFile: function () {
var self = this;
var fileToRemove = this.get('fileToRemove');
fileToRemove .destroyRecord().then(function(){
self.get('model').removeObject(file);
});
}
However, I chose to be conservative and double-check the store. That seems safer to me.