Fullcalendar, Resources as function don't work - fullcalendar

I'm working with Fullcalendar and I'm trying to get resources as function
resources: function(callback){
var manageEvent = new ManageEvent();
var request = manageEvent.getEmployees();
request.always(function (param) {
//location.reload();
var list = [];
var emp;
for (var elem in param) {
emp = param[elem];
list.push({
'id': emp['cp_collaboratore'],
'title': emp['cognome_col']
});
}
var t = JSON.stringify(list);
callback(t);
});
request.catch(function (param) {
alert('errore');
});
},
I checked the variable 't' through log and it shows the following result:
[{"id":"1","title":"name_1"},{"id":"2","title":"name_2"},{"id":"3","title":"name_3"},{"id":"5","title":"name_4"},{"id":"9","title":"name_5"}]
but it don't works and shows the following error message:
Uncaught TypeError: resourceInputs.map is not a function
at ResourceManager.setResources

You just need to write
callback(list);
t in your code is a string, because you converted your list array into a string using JSON.stringify(). But fullCalendar expects an actual array, not a string. It can't run functions or read individual properties from a string.
You can remove the line var t = JSON.stringify(list); completely, it's not needed.
Generally the only reason you'd use stringify() is if you wanted to log the value to your console for debugging, or convert the array into JSON if you wanted to send it somewhere else using AJAX. It makes no sense to pass arrays and objects around inside JavaScript as serialised strings, when you can just use the objects themselves.

Related

Cannot encode type ([object Object]) to a Firestore Value error while attempting pagination

So here I have my code
notifull.get('/getNote', (request, response) => {
// START Get variables
var requestData = {
// location properties
subject: request.query.subject,
category: request.query.category,
subcategory: request.query.subcategory,
// easy way to get full reference string
referenceString: function() {
return `${this.subject}/${this.category}/${this.subcategory}`;
},
// pagination properties
pagePosition: Number(request.query.pagePosition),
// easy way to get limit number
paginationNumber: function() {
return (this.pagePosition - 1) * 2;
}
};
// DEBUG_PURPOSES response.send(requestData.referenceString());
// END Get variables
// START Construct index
var first = admin.firestore().collection(requestData.referenceString())
.orderBy("upvotes")
.limit(requestData.paginationNumber());
// DEBUG_PURPOSES response.send(first)
// END Construct index
// START Paginate
return first.get().then(function (documentSnapshots) {
// Get the last visible document
var lastVisible = documentSnapshots.docs[documentSnapshots.docs.length-1];
console.log("last", lastVisible);
// Construct a new query starting at this document,
// get the next 25 cities.
var next = admin.firestore().collection(requestData.referenceString())
.orderBy("upvotes")
.startAfter(lastVisible)
.limit(2);
response.send(next)
});
});
As you can see, I am attempting to Paginate using Cloud Firestore. If you'll notice, I've divided the code into sections, and the previous testing shows me the Construct Index and Get variables sections work. However, when I pulled the Paginate example from Firebase's own docs, adapted it to my code, and then tried to run, I was met with this error.
Cannot encode type ([object Object]) to a Firestore Value
UPDATE: After more testing, it seems that if I remove the startAfter line, it works fine.
According to firebase documentation, Objects of custom classes are not supported so in some languages like PHP, C++, Python and Node.js.
PLEASE HERE AS A REFERENCE.
https://firebase.google.com/docs/firestore/manage-data/add-data#custom_objects
So, I can advise to encode your objects to json and be decoding them to your custom classes when you download them from firebases.

Exception in template helper: Error: Match error

I'm trying to perform a custom sort using a comparator function from within a template helper in Meteor.
Here is my template helper:
Template.move_list.helpers({
assets() {
return Assets.find({}, { sort: sortFunction });
}
});
And here is the comparator function:
const sortFunction = function (doc1, doc2) {
const barcodes = Session.get('barcodesArray');
if (barcodes.indexOf(doc1.barcode) === -1 || barcodes.indexOf(doc2.barcode) === -1) {
return 0;
}
let last = null;
_.each(barcodes, function (barcode) {
if (barcode === doc1.barcode) last = doc1.barcode;
if (barcode === doc2.barcode) last = doc2.barcode;
});
return last === doc1.barcode ? 1 : -1;
}
Error
When the page loads, the following error is returned:
Exception in template helper: Error: Match error: Failed Match.OneOf, Match.Maybe or Match.Optional validation
I put a breakpoint in chrome into the sortFunction, however the function was never entered and the breakpoint never reached.
Of course, the error is not throw when I remove sort.
References
This feature is not very well documented, however here is the relevant part of the docs:
For local collections you can pass a comparator function which receives two document objects, and returns -1 if the first document comes first in order, 1 if the second document comes first, or 0 if neither document comes before the other. This is a Minimongo extension to MongoDB.
And the commit by mitar adding the functionality, with example code from the test:
var sortFunction = function (doc1, doc2) {
return doc2.a - doc1.a;
};
c.find({}, {sort: sortFunction})
Can anyone make sense of this error?
Edit:
This issue should be resolved in Meteor >= v1.3.3.1.
Local collections (i.e, client-side and in-memory server-side collections) will allow to pass a function as the sort clause.
The error comes from the mongo package, where the spec does not allow sort to be a function.
#mitar changed LocalCollection in the minimongo package. LocalCollection is part of the Mongo.Collection object on the client (its _collection attribute), but queries are still checked according to the original mongo spec. I believe this to be a bug, as the spec was not updated to reflect the change.
To overcome this (in the meantime), either have the function accept a sub-field, such that the sort value is an object:
var sortFunction = function (x, y) {
return x - y;
};
c.find({}, {sort: {a: sortFunction}});
or use the c._collection.find() instead, which will work (as far as I can tell), except it will not apply any transformations defined for the collection.
var sortFunction = function (doc1, doc2) {
return doc2.a - doc1.a;
};
c._collection.find({}, {sort: sortFunction});

meteor restivus how to read multiple queryParams

I am building an API with Restivus in Meteor.
In a custom route I would like to have multiple values as queryParams like this (e.g. value1 and value2):
...domain/api/update?key=1234&value1=10
How do I get them in endpoint function?
When I try this I get undefined:
var query = this.queryParams.key // result: 1234
var value1 = this.queryParams.value1 // result: undefined
Update
This is my new fresh code with the same result.
Use a standard Meteor project. Meteor version 1.0.3.2
// Create collection
Posts = new Mongo.Collection("posts");
if (Meteor.isServer) {
Meteor.startup(function () {
// RESTIVUS
// Global configuration
Restivus.configure({
useAuth: false,
prettyJson: true
});
// Given the url: "/posts?key=1234&value1=10"
Restivus.addRoute('posts', {
get: function () {
var key = this.queryParams.key;
var value1 = this.queryParams.value1;
console.log("key: " + key); // result: 1234
console.log("value1: " + value1); // result: undefined
}
});
});
}
This is the solution to the problem. Taken from here:
https://github.com/kahmali/meteor-restivus/issues/16
You're using curl to test, right? Well apparently (and don't feel bad for not knowing this, because neither did I), the & symbol means that the previous command will be run in the background, so the query params were just being truncated once the curl command reached the & for the second query param. All you have to do is wrap the URL in quotes, and voila! Try this command instead:
curl "http://testivus.meteor.com/api/posts?key=1234&value1=10"
That should work. So if you had just punched that URL into a browser or used a mored advanced REST client, you would have seen the extra query param defined. I got the answer from this StackOverflow question.

angularFireCollection is not returning any data

I have no issues when using implicit updates (angelFire). However I need for some of my data use explicit updating. So I implemented angelFireCollection on the exact same ref I was using previously but despite the console.log explicitly saying that the read was granted and trying it with both with the onloadcallback and without, I don't get data directly into my assigned variable AND once the callback fires I get a strange looking object that DOES contain the data but not in the form I expect. My scope variable ends up with an empty collection. Never gets populated. Here is the code:
var streamController = function ($rootScope, $scope, $log, $location, angularFireCollection, profileService) {
//Wait for firebaseLogin...
$rootScope.$watch('firebaseAuth', init);
function init() {
if ($rootScope.firebaseAuth == false) {
return
};
var refUsers = new Firebase($rootScope.FBURL+'/users/'+$rootScope.uid);
$scope.profile = angularFireCollection(refUsers, function onload(snapshot) {
console.log(snapshot)
});
};
};
myApp.gwWebApp.controller('StreamController', ['$rootScope', '$scope', '$log', '$location', 'angularFireCollection', 'profileService',
streamController]);
}());
Here is what the console.log looks like ( ie; what snapshot looks like ):
>snapshot
T {z: R, bc: J, V: function, val: function, xd: function…}
Here is the earlier message before the snapshot was returned:
Firebase Login Succeeded! fbLoginController.js:16
FIREBASE: Attempt to read /users/529ccc5d1946a93656320b0a with auth={"username":"xxxxxxx#me.com","id":"529ccc5d1946a93656320b0a"} firebase.js:76
FIREBASE: /: "auth.username == 'admin'" firebase.js:76
FIREBASE: => false firebase.js:76
FIREBASE: /users firebase.js:76
FIREBASE: /users/529ccc5d1946a93656320b0a: "auth.id == $user" firebase.js:76
FIREBASE: => true firebase.js:76
FIREBASE:
FIREBASE: Read was allowed.
and finally the desired binding that ends up with an empty array: again from the console:
$scope.profile
[]
Anyone know what I could possibly be doing wrong?? This is like 5 lines of code. Frustrating.
I have put stops in angelFireCollection factory function and can see that the data is getting added to the collection in the callbacks inside that function but my binded variable never gets updated.
UPDATE
Ok experimenting with a plnkr. It seems that angularFireCollection EXPECTS your returning a LIST of items. The snapshot returns properly if you inspect snapshot.val() it will be whatever object structure was stored in firebase. IF you use angularFireCollection it does indeed bind to the variable HOWEVER it turns a non-list object into a garbled mess and you can not access the object user the normal dot operator. This is either a bug or it is a severe limitation of angularFireCollection which will cause me to revaluate how easily I can use firebase as the backend. I can't share my plnkr because it is accessing non-public data but tomorrow if i have time I will create a public firebase with an object store and demonstrate.
Ok. So it appears that indeed angularFireCollection is MEANT to be array based. Which is fine. It would be VERY helpful if the angularFire documentation was updated to make that clear. As such it is not an implicit vs explicit update technique.
For an explicit non-array based approach I have come up with the following code. Had I not been mislead by the documentation I would have gone down this path originally.
var MainCtrl = function($scope, angularFire) {
$scope.test = {};
var _url = 'https://golfwire.firebaseio.com/tmp';
var _ref = new Firebase(_url);
var promise = angularFire(_ref, $scope, 'implicit');
promise.then ( function(data){
$scope.explicit=angular.copy($scope.implicit );
});
}
You then work locally with the 'explicit' copy and when ready just update the 'implicit' by assigning: $scope.implicit = $scope.explicit.
Here is a plnkr: http://plnkr.co/edit/bLJrL1

How to insert documents in a loop?

I am iterating over a moment-range daterange and trying to insert documents. I am getting the following error:
Exception while simulating the effect of invoking '/carpool_events/insert'
Error
Error: Sorting not supported on Javascript code
at Error (<anonymous>)
at Object.LocalCollection._f._cmp (http://localhost:3000/packages/minimongo/selector.js? 5b3e1c2b868ef8b73a51dbbe7d08529ed9fb9951:251:13)
at Object.LocalCollection._f._cmp (http://localhost:3000/packages/minimongo/selector.js? 5b3e1c2b868ef8b73a51dbbe7d08529ed9fb9951:226:36)
at LocalCollection._f._cmp (http://localhost:3000/packages/minimongo/selector.js?5b3e1c2b868ef8b73a51dbbe7d08529ed9fb9951:218:33)
at _func (eval at <anonymous> (http://localhost:3000/packages/minimongo/sort.js?08a501a50f0b2ebf1d24e2b7a7f8232b48af9057:63:8), <anonymous>:1:51)
at Function.LocalCollection._insertInSortedList (http://localhost:3000/packages/minimongo/minimongo.js?7f5131f0f3d86c8269a6e6db0e2467e28eff6422:616:9)
at Function.LocalCollection._insertInResults (http://localhost:3000/packages/minimongo/minimongo.js?7f5131f0f3d86c8269a6e6db0e2467e28eff6422:534:31)
at LocalCollection.insert (http://localhost:3000/packages/minimongo/minimongo.js?7f5131f0f3d86c8269a6e6db0e2467e28eff6422:362:25)
at m.(anonymous function) (http://localhost:3000/packages/mongo-livedata/collection.js?3ef9efcb8726ddf54f58384b2d8f226aaec8fd53:415:36)
at http://localhost:3000/packages/livedata/livedata_connection.js?77dd74d90c37b6e24c9c66fe688e9ca2c2bce679:569:25
This is my loop with the insert. I have tested the loop by just writing to console.log instead of inserting and the loop works fine
'click button.save-addEventDialogue': function(e, tmpl) {
var start = Session.get("showAddEventDialogue_dateRangeStart");
var end = Session.get("showAddEventDialogue_dateRangeEnd");
var dateRange = moment().range(moment(start),moment(end));
var dateLoopIncrement = moment().range(moment(start),moment(start).add('days',1));
console.log(dateRange);
console.log(dateLoopIncrement);
// Loop through the date range
dateRange.by(dateLoopIncrement, function(moment) {
// Do something with `moment`
var dateToSave = dateRange.start;
// Insert the record
Carpool_Events.insert({
owner: Meteor.user().profile.name,
owner_id: Meteor.userId(),
original_owner: Meteor.user().profile.name,
original_owner_id: Meteor.userId(),
declined: 0,
date: dateToSave.toDate()
});
dateToSave.add('days',1);
});
// Clear the Session
Session.set("showAddEventDialogue_dateRangeStart","");
Session.set("showAddEventDialogue_dateRangeEnd","");
// Close the dialogue
Session.set("showAddEventDialogue", false);
}
What is the right way to do this? Thanks.
The error message Sorting not supported on Javascript code is a result of inserting a JavaScript function (!) into a collection -- for example, by doing something like Carpool_Events.insert({x: function () { ... }}); JavaScript functions should not normally go into collections.
Somewhere in your code there is probably a typo where you are not calling a function (for example, writing Meteor.userId on the client instead of Meteor.userId().) My guess would be that in the process of making your code run on the server, you coincidentally fixed or avoided this.
I wasn't able to visually find the problem in your code -- if I'm wrong, to make more progress it would be helpful to have a reproduction.
It looks like the issue occurs when doing a bulk inserts (inserts in a loop) from the client. What I ended up doing was using a Meteor.methods to execute the insert on the server side. This seemed to workaround whatever the issue of doing this on the client is.
I also realized that I don't need to iterate over the dates using moment-range. Instead i just use moment to get the difference in days and iterate over that.
JS code in the client:
'click button.save-addEventDialogue': function (e, tmpl) {
var start = moment(Session.get("showAddEventDialogue_dateRangeStart"));
var end = moment(Session.get("showAddEventDialogue_dateRangeEnd"));
var days = end.diff(start, 'days');
var count = 0;
var dateToSave = moment(start);
// Loop through the date range
for (count; count <= days; count++) {
Meteor.call('bulkInsertCarpoolEvent', Meteor.user(), dateToSave.toDate());
dateToSave.add('days', 1);
};
// Clear the Session
Session.set("showAddEventDialogue_dateRangeStart", "");
Session.set("showAddEventDialogue_dateRangeEnd", "");
// Close the dialogue
Session.set("showAddEventDialogue", false);
}
On the server:
Meteor.startup(function () {
Meteor.methods({
bulkInsertCarpoolEvent: function (user, date) {
return Carpool_Events.insert({
owner: user.profile.name,
owner_id: this.userId,
original_owner: user.profile.name,
original_owner_id: this.userId,
declined: 0,
date: date
});
}
});
});

Resources