I have a code that retrives a simple json array and i just want to loop
var ref = new Firebase("firebase object path");
var sync = $firebase(ref);
var result = sync.$asArray();
and then i can't get the json array length using "result.length" it just give a result of 0 length but not the exact value can anyone help me...?
Probably because it's not loaded yet. Looks like you're using an old verison of angularFire as $asArray is deprecated see: When does one use $asArray vs $asObject in Angularfire?, https://github.com/firebase/angularfire/blob/master/docs/migration/09X-to-1XX.md
Once you've upgraded (if you can)
$firebaseArray(ref).$loaded().then(function(data){
console.log(data.length)
});
I can't seem to find the docs for when $asArray was around but looking through the second link up there I think you can accomplish it like this:
sync.$asArray().$loaded().then(function(array) {
console.log(array.length);
});
With a watch:
$scope.data = [];
sync.$asArray().$loaded().then(function (array) {
$scope.data = array;
});
$scope.$watch('data', function (newValue, oldValue) {
console.log($scope.data.length);
});
Related
Iam trying to create a custom filter to filter matching array of values in angularjs. Array Structure below
["tag1","tag2"]
Now I need to filter all objs having tags matching id1,id2.. Below is the filter I have tried
var autoFilter = angular.module("autoFilters",[]);
autoFilter.filter('arrayData', function (){
return function(){
return ["id1","id2"];
}
//$scope.arrayValues = ["id1","id2"];
});
and UI code below
<li style="cursor:pointer" ng-cloak class="list-group-item" ng-repeat="values in suggestionResults | arrayData">{{values.id}} -- {{values.title}}</li>
But Data is not showing up. Can you help me out where Iam doing wrong. Plunker Code available below
plunker here
see the code below :) This is not the best approach in my opinion and will definitely have some performance issue with larger lists, but it does the work (now I used indexOf(2) but there you can pass any truthy/falsy argument)
var autoFilter = angular.module("autoFilters",[]);
autoFilter.controller("filterController",['$scope','$http', function ($scope,$http) {
$scope.searchSuggest = function(){
//$http({method: 'GET', url: 'json/searchSuggestions.json'}).success(function(data) {
$http.get("assets.json").then(function(response) {
//var str = JSON.stringify(response);
//var arr = JSON.parse(str);
$scope.suggestionResult = response.data;
console.log($scope.suggestionResult);
//$scope.arrayData = ["asset_types:document/data_sheet","asset_types:document/brochure"];
}).catch(function activateError(error) {
alert('An error happened');
});
}
$scope.showProduct = function(){
}
}]);
autoFilter.filter('arrayData', function (){
return function(data){
// if you are using jQuery you can simply return $.grep(data, function(d){return d.id.indexOf('2') >-1 });
return data.filter(function(entry){
return entry.id.indexOf('2') > -1
})
}
});
Having experienced working with large lists I would, however, suggest you to avoid using a separate filter for this and rather manipulate it in the .js code. You could easily filter the data when you query it with your $http.get like:
$scope.suggestionResult = response.data.filter(function(){
return /* condition comes here */
}
This way you are not overloading the DOM and help the browser handling AngularJS's sometimes slow digest cycle.
If you need it to be dynamic (e.g. the filtering conditions can be changed by the user) then add an ng-change or $watch or ng-click to the modifiable information and on that action re-filter $scope.suggestionResult from the original response.data
I am trying to see if a value in the "apply" sublist for customer payment data has changed and do some action based on it.
My SuiteScript is as follows:
define(['N/record', 'N/https'],
function(record,https)
{
function afterSubmit(context)
{
var oldRec = context.oldRecord;
log.debug({title: 'oldRec ', details: oldRec });
// This log shows that the JSON has an
// attribute called sublists which contains "apply" which has all the applied payments
// eg: {"id":"1234", "type":"customerpayment", "fields":{all the fields},
// "sublists": {"apply" : {"line 1"...}}}
var oldRecSublists = oldRec.sublists;
log.debug({title: 'oldRecApply ', details: oldRecSublists });
// This returns empty or null though there is data
What am I doing wrong here?
Basically what I am trying to achieve is compare the context.oldRecord.sublists.apply and context.newRecord.sublists.apply to find if the amt has changed or not.
Is there a better way to do this is SuiteScript 2.0?
Thanks in advance!
Part of what is going on there is that it looks like you are trying to spelunk the NS data structure by what you see in the print statement. You are not using the NS api at all.
When you send the NS object to the log function I believe it goes through a custom JSON.stringify process so if you want to just inspect values you can do:
var oldRecObj = JSON.parse(JSON.stringify(oldRec));
now oldRecObj can be inspected as though it were a simple object. But you won't be able to manipulate it at all.
You should be using the NS schema browser
and referring to the help docs for operations on N/record
A snippet I often use for dealing with sublists is:
function iter(rec, listName, cb){
var lim = rec.getLineCount({sublistId:listName});
var i = 0;
var getV = function (fld){
return rec.getSublistValue({sublistId:listName, fieldId:fld, line:i});
};
var setV = function(fld, val){
rec.setSublistValue({sublistId:listName, fieldId:fld, line:i, value:val});
};
for(; i< lim; i++){
cb(i, getV, setV);
}
}
and then
iter(oldRec, 'apply', function(idx, getV, setV){
var oldApplied = getV('applied');
});
I am trying out some angularjs stuff. So I have a few arrays. One of them is artists. this is it's basic structure from console.log(artists);
artists
problem is that I can't access the elements of the array individually. I read up a lot of things regarding associative arrays and may questions on SO but none really helped. So either it is a very silly mistake I am making or it is some thing else.
Here are few results that I got with every array I have.
console.log(artists[0]); //returns undefined
console.log(artists['0']); //returns undefined
console.log(artists.length); // returns 0 in spite of the fact it showed 20 previously
console.log(Array.isArray(artists)); //returns true
And yes I created the array like this in a service, ChartService
var artists = [];
var artistids = [];
var tracks = [];
$http.get('https://api.spotify.com/v1/search/?q=genre:pop&type=artist').success(function (data) {
var items = data.artists.items;
items.forEach(function(item){
artists.push(item.name);
artistids.push(item.id);
var query = trackApi+item.id+'/top-tracks?country=SE'
$http.get(query).success(function (response) {
tracks.push({'preview': response.tracks[0].preview_url});
});
});
});
return {
Artists : artists,
Tracks : tracks
}
And my controller
console.log(ChartService.Artists); //runs fine
console.log(ChartService.Tracks); //runs fine
$scope.tracks = ChartService.Tracks;
console.log($scope.tracks); //runs fine
console.log($scope.tracks[0]); //returns undefined
console.log($scope.tracks['0']); //returns undefined
console.log($scope.tracks.length); // returns 0 in spite of the fact it showed 20 previously
console.log(Array.isArray($scope.tracks)); //returns true
The issue is that you check the content of artists before the issued http get requests have triggered their responses.
One way to resolve that is to put your code in the success callback, like this:
$http.get('https://api.spotify.com/v1/search/?q=genre:pop&type=artist').success(function (data) {
var items = data.artists.items;
items.forEach(function(item){
artists.push(item.name);
artistids.push(item.id);
var query = trackApi+item.id+'/top-tracks?country=SE'
$http.get(query).success(function (response) {
tracks.push({'preview': response.tracks[0].preview_url});
});
});
// here
console.log(artists);
});
Still, that solves it for artists, but then you'd need to do something similar if you need the tracks: as you have more then one request providing for that, you'd need to check the length of the tracks array and only if it has the complete length, like this:
$http.get('https://api.spotify.com/v1/search/?q=genre:pop&type=artist').success(function (data) {
var items = data.artists.items;
items.forEach(function(item){
artists.push(item.name);
artistids.push(item.id);
var query = trackApi+item.id+'/top-tracks?country=SE'
$http.get(query).success(function (response) {
tracks.push({'preview': response.tracks[0].preview_url});
if (tracks.length == items.length) { // all done
console.log(artists, tracks);
}
});
});
});
In a follow-up question (in comments) you explained you need this in your controller. You might look into $watch or variants of that method. If you need assistance with that, I would suggest to ask a new question.
I have a rather simple question. I have a simple controller and its $scope.coords = []; renders JSON in HTML:
[24.43359375, 54.6611237221]
[25.2905273438, 54.6738309659]
[25.3344726562, 54.6102549816]
[25.2685546875, 54.6801830971]
[25.2960205078, 54.6611237221]
How can I render that JSON not in html, but in my controller itself ? The code looks like that. Please see the comment in code:
propertyModule.controller('propertyController', ['$scope', 'Property', function ($scope, Property) {
// Query returns an array of objects, MyModel.objects.all() by default
$scope.properties = Property.query();
// Getting a single object
$scope.property = Property.get({pk: 1});
$scope.coords = [];
$scope.properties = Property.query({}, function(data){
console.log(data);
angular.forEach(data , function(value){
$scope.coords.push(value.coordinates);
});
});
$scope.positions = //$Resource('realestate.property').items();
[
[54.6833, 25.2833], [54.67833, 25.3033] // those coordinates are hardcoded now, I want them to be rendered here by $scope.coords
];
}]);
First off, you're showing us a bunch of arrays, not a JSON document. But since your code seems to be working, I'll assume you do have a valid JSON to work with.
You need to consider the fact that you are making an asynchronous request here :
$scope.properties = Property.query({}, function(data) {
console.log(data);
angular.forEach(data , function(value){
$scope.coords.push(value.coordinates);
});
});
This means you won't be able to fetch data from $scope.coords before anything has arrived.
There are several ways to solve that :
You could simply fetch data while you're still in the loop :
angular.forEach(data , function(value) {
$scope.coords.push(value.coordinates);
if('your condition') {
$scope.positions.push(value.coordinates);
}
});
You could use a promise, see the angular doc.
Or you could watch over $scope.coords with $scope.$watch.
I'm trying to convert my basic crud operations into an API that multiple components of my application can use.
I have successfully converted all methods, except the update one because it calls for each property on the object to be declared before the put request can be executed.
controller
$scope.update = function(testimonial, id) {
var data = {
name: testimonial.name,
message: testimonial.message
};
dataService.update(uri, data, $scope.id).then(function(response) {
console.log('Successfully updated!');
},
function(error) {
console.log('Error updating.');
});
}
dataService
dataService.update = function(uri, data, id) {
var rest = Restangular.one(uri, id);
angular.forEach(data, function(value, key) {
// needs to be in the format below
// rest.key = data.key
});
// needs to output something like this, depending on what the data is passed
// rest.name = data.name;
// rest.message = data.message;
return rest.put();
}
I tried to describe the problem in the codes comments, but to reiterate I cannot figure out how to generate something like rest.name = data.name; without specifying the name property because the update function shouldn't need to know the object properties.
Here is what the update method looked like before I started trying to make it usable by any of my components (this works)
Testimonial.update = function(testimonial, id) {
var rest = Restangular.one('testimonials', id);
rest.name = testimonial.name;
rest.message = testimonial.message;
return rest.put();
}
How can I recreate this without any specific properties parameters hard-coded in?
Also, my project has included lo-dash, if that helps, I don't know where to start with this problem. Thanks a ton for any advice!
Try like
angular.extend(rest,testimonial)
https://docs.angularjs.org/api/ng/function/angular.extend