I am creating a simple web application in which a user can click the follow button on a photo story (post which stores an image, title, story, username) and start following that user. The problem is that when i click the button i get the:
Uncaught RangeError: Maximum call stack size es5-shim.js:888 exceeded
at Object.toString (<anonymous>)
at isArguments (es5-shim.js:888)
at Function.keys (es5-shim.js:951)
at Function._.each._.forEach (underscore.js:111)
at Object.EJSON.clone (ejson.js:500)
at ejson.js:501
at Function._.each._.forEach (underscore.js:113)
at Object.EJSON.clone (ejson.js:500)
at ejson.js:501
at Function._.each._.forEach (underscore.js:113)
The app is running meteor 1.2.1. I updated to 1.3 but it didn’t fix the problem. I updated to 1.4 and 1.5 but my code is not running in these versions of meteor.I also created the same project without the photos so the users can post only a text and the follow button works fine. So i don’t know where the problem is. Below i am providing a part of the code from the version with the photos and the lines that are different between the 2 versions.
The code: collections.js:
Post = new Mongo.Collection('post');
if(Meteor.isClient) {
Template.postsList.helpers({
posts: function(){
return Post.find();
}
})
}
Images = new FS.Collection('Images', {
stores: [new FS.Store.GridFS('Images')],
filter: {
allow: {
contentTypes: ['image/*']
},
onInvalid: function(message) {
FlashMessage.sendError(message);
}
}
});
Images.allow({
insert:function(){return true;},
update:function(){return true;},
download:function(){return true;}
});
methods.js:
Meteor.methods({
addImageInfo: function(imageId, title, story){
if(!Meteor.userId()){
throw new Meteor.Error('Not Authorized');
}
var username = Meteor.user().username;
//var username2 = Meteor.user().profile.name;
Post.insert({
title: title,
content: story,
imageId: imageId,
imageUrl: '/cfs/files/Images'+imageId,
userId: Meteor.userId(),
username: username,
username2: Meteor.user().profile.name,
createdAt: new Date()
});
},
deleteImage: function(imageId){
if(!Meteor.userId()){
throw new Meteor.Error('Not Authorized');
}
Images.remove(imageId);
//This removes the post's infomation and the image
imageInfoId = Post.findOne({imageId:imageId})._id;
Post.remove(imageInfoId);
},
follow: function(post){
console.log(post);
}
});
postForm.js:
Template.postForm.events({
'submit .add-image-info': function(event){
event.preventDefault();
var title = document.getElementById('name').value;
var story = document.getElementById('story').value;
var imageId = Session.get('imageId');
console.log(name);
console.log(story);
Meteor.call('addImageInfo', imageId, title, story)
event.target.reset();
Modal.hide('addInfo');
FlashMessages.sendSuccess('Image Info Added');
return false;
}
})
images.js:
Template.postsList.helpers({
images: function(){
return Images.find({}, {sort:{uploadedAt: -1}});
}
});
Template.image.helpers({
'isOwn': function(imageId){
var owner = Post.findOne({imageId: imageId}).userId;
if(owner == Meteor.userId()) {
return true;
} else {
return false;
}
}
});
Template.image.events({
'click .remove-image': function(event){
if(confirm('Are You sure?')){
Meteor.call('deleteImage', this._id );
FlashMessages.sendSuccess('Image Removed');
return false;
}
}
});
imageInfo.js which i am getting the title the content and the username of the post
Template.imageInfo.helpers({
getTitle: function(imageId) {
return Post.findOne({imageId: imageId}).title;
},
getStory: function(imageId) {
return Post.findOne({imageId: imageId}).content;
},
getUsername: function(imageId) {
return Post.findOne({imageId: imageId}).username;
},
getUsername2: function(imageId) {
return Post.findOne({imageId: imageId}).username2;
}
});
//here i am creating an event listener on the 'follow' link
Template.imageInfo.events({
'click .follow-link': function(event){
event.preventDefault();
Meteor.call('follow', this);
}
});
imageInfo.html:
<template name="imageInfo">
<div class="imageInfo">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-tittle">{{getTitle _id}} <span class="pull-right">Posted by: {{getUsername _id}} {{getUsername2 _id}}</span></h4>
<a class="follow-link">Follow</a>
</div>
<div class="panel-body">
{{getStory _id}}
</div>
</div>
</div>
</template>
dropzone.js:
Template.dropzone.events({
'dropped #dropzone': function(event){
FS.Utility.eachFile(event, function(file){
var newFile = new FS.File(file);
Images.insert(newFile, function(error, result){
if(error){
FlashMessages.sendError('There was an issue with upload')
} else {
Session.set('imageId', result._id);
FlashMessages.sendSuccess('Image Uploaded');
//Modal.show('addInfo');
}
});
});
}
});
The difference between the two versions is that instead of using:
getTitle: function(imageId) {
return Post.findOne({imageId: imageId}).title;
},
getStory: function(imageId) {
return Post.findOne({imageId: imageId}).content;
},
getUsername: function(imageId) {
return Post.findOne({imageId: imageId}).username;
},
getUsername2: function(imageId) {
return Post.findOne({imageId: imageId}).username2;
}
i am using for the simple version:
result = Post.find({}, {sort: {created: -1}});
and on the HTML instead of :
{{getTitle _id}} {{getStory}} and {{getUsername}}
i am using:
{{#each posts}}
{{content}}
{{username}}
{{/each}}