Global variable Meteor - javascript

Theres is a Meteor Windows Release bug?
When I try this, works:
//Main File
Persons = {}
Persons.person = {name : "Roger", age : 30}
//Another file
console.log(Persons.person);
But when I call in another JS, like the code bellow, with a "console.log("Persons")" dont works:
PersonsCollection = new Mongo.Collection("persons");
Meteor.subscribe("allPersons");
// THIS CODE
console.log(Persons);
if (Meteor.isServer) {
PersonsCollection.allow({
insert : function () {
if(Roles.userIsInRole(Meteor.userId(), ['admin'])){
return true;
} else{
return false;
}
},
update : function () {
if(Roles.userIsInRole(Meteor.userId(), ['admin'])){
return true;
} else{
return false;
}
},
remove : function () {
if(Roles.userIsInRole(Meteor.userId(), ['admin'])){
return true;
} else{
return false;
}
}
});
}
The structure:
models/personsCollection.js //Bug here
models/test1.js //I have created the global var here
models/test2.js //I called here

Related

Code review? Is there a way to write this better?

I have some code.
$(this).find('.change--button__approve').click(function(){
if ($(this).hasClass('disabled')) {
return false;
} else {
$(thisChange).attr('data-type', 'approved').attr('data-changeRule', 'once');
$(this).parent().parent().next().find('p').attr('class','approved').addTemporaryClass('bounceIn', 500);
$(this).parent().parent().next().find('.changeStatus').text('approved for this document');
}
});
$(this).find('.change--button__approveAlways').click(function(){
if ($(this).hasClass('disabled')) {
return false;
} else {
$(thisChange).attr('data-type', 'approved').attr('data-changeRule', 'always');
$(this).parent().parent().next().find('p').attr('class','approved').addTemporaryClass('bounceIn', 500);
$(this).parent().parent().next().find('.changeStatus').text('approved for every document');
}
});;
$(this).find('.change--button__reject').click(function(){
if ($(this).hasClass('disabled')) {
return false;
} else {
$(thisChange).attr('data-type', 'rejected').attr('data-changeRule', 'once');
$(this).parent().parent().next().find('p').attr('class','rejected').addTemporaryClass('bounceIn', 500);
$(this).parent().parent().next().find('.changeStatus').text('rejected for this document');
}
});;
$(this).find('.change--button__rejectAlways').click(function(){
if ($(this).hasClass('disabled')) {
return false;
} else {
$(thisChange).attr('data-type', 'rejected').attr('data-changeRule', 'always');
$(this).parent().parent().next().find('p').attr('class','rejected').addTemporaryClass('bounceIn', 500);
$(this).parent().parent().next().find('.changeStatus').text('rejected for every document');
}
});;
Because of the repetitive nature of the code, I figured there must be a better way to write this. I'm still a js beginner so I'd love to know how to write this cleaner/better.
Thanks!
Here is an optimized code :
var _this = $(this);
_this.find('.change--button__approve').click(function() {
var sibling, _this = $(this);
if (_this.hasClass('disabled')) {
return false;
} else {
$(thisChange).attr('data-type', 'approved').attr('data-changeRule', 'once');
sibling = _this.parent().parent().next();
sibling.find('p').attr('class','approved').addTemporaryClass('bounceIn', 500);
sibling.find('.changeStatus').text('approved for this document');
}
});
_this.find('.change--button__approveAlways').click(function() {
var sibling, _this = $(this);
if (_this.hasClass('disabled')) {
return false;
} else {
$(thisChange).attr('data-type', 'approved').attr('data-changeRule', 'always');
sibling = _this.parent().parent().next();
sibling.find('p').attr('class','approved').addTemporaryClass('bounceIn', 500);
sibling.find('.changeStatus').text('approved for every document');
}
});
_this.find('.change--button__reject').click(function() {
var sibling, _this = $(this);
if (_this.hasClass('disabled')) {
return false;
} else {
$(thisChange).attr('data-type', 'rejected').attr('data-changeRule', 'once');
sibling = _this.parent().parent().next();
sibling.find('p').attr('class','rejected').addTemporaryClass('bounceIn', 500);
sibling.find('.changeStatus').text('rejected for this document');
}
});
_this.find('.change--button__rejectAlways').click(function() {
var sibling, _this = $(this);
if (_this.hasClass('disabled')) {
return false;
} else {
$(thisChange).attr('data-type', 'rejected').attr('data-changeRule', 'always');
// Store into a variable to optimize execution speed
sibling = _this.parent().parent().next();
sibling.find('p').attr('class','rejected').addTemporaryClass('bounceIn', 500);
sibling.find('.changeStatus').text('rejected for every document');
}
});
As you see, the main problem is the using of $(this).parent().parent().next() on two simultaneous lines, which cause speed issue. By storing it in a local variable, this function chain is not runned two times, and the local variable is deleted after usage.
The second problem (less important) is the repetitive usage of $(this) which needs to create a jQuery instance each time you use it. By storing it in a local variable _this you can use at as often as you want without causing a instanciation that takes time.
EDIT : Another more complex but better way is this one :
var _this = $(this);
var details = {
'approve': ['once', 'approved', 'approved for this document'],
'approveAlways': ['always', 'approved', 'approved for every document'],
'reject': ['once', 'rejected', 'rejected for this document'],
'rejectAlways': ['always', 'rejected', 'rejected for every document']
}, keys = Object.keys(details);
for(var i = 0; i < keys.length; i++)
// Create a lambda function to use local variable 'scope'
(function(scope) {
// Here is the content of 'scope' :
// scope[0] : value of 'data-changeRule' ('once' or 'always')
// scope[1] : value of 'data-type' and 'class' ('approved' or 'rejected')
// scope[2] : message to display 'approved for this document'...
_this.find('.change--button__' + scope[3]).click(function() {
var sibling, _this = $(this);
if (_this.hasClass('disabled')) {
return false;
} else {
$(thisChange).attr('data-type', scope[1]).attr('data-changeRule', scope[0]);
sibling = _this.parent().parent().next();
sibling.find('p').attr('class', scope[1]).addTemporaryClass('bounceIn', 500);
sibling.find('.changeStatus').text(scope[2]);
}
});
}).call(this, details[keys[i]].concat([keys[i]])); // Call the lambda function with its informations
Please note that this code is not optimized as best I can but if I optimize it it will be ugly.
EDIT 2 : This is, I think, the faster and better way to do your stuff :
var _this = $(this),
keys = ['approve', 'approveAlways', 'reject', 'rejectAlways'];
for(var i = 0; i < keys.length; i++)
// Create a lambda function to use local variable 'scope'
(function(name) {
_this.find('.change--button__' + name).click(function() {
var sibling, _this = $(this),
approve = (name.indexOf('approve') !== -1 ? 'approved' : 'rejected'), // Is the button an approving or rejecting button ?
always = (name.indexOf('Always') !== -1); // Is the button setting always or only for THIS document ?
if (_this.hasClass('disabled')) {
return false;
} else {
$(thisChange).attr('data-type', approve).attr('data-changeRule', (always ? 'always' : 'once'));
sibling = _this.parent().parent().next();
sibling.find('p').attr('class', approve).addTemporaryClass('bounceIn', 500);
sibling.find('.changeStatus').text(approve + ' for ' + (always ? 'every' : 'this') + ' document');
}
});
}).call(this, keys[i]); // Call the lambda function with its informations
Only a few strings are stored and your function _this.find('.change--button__...').click( is writed one time only and runned by the loop multiple times. If you want to add buttons, you can simply add their name in the array keys.
I hope I helped you :)
try storing your strings
'.change--button__approve', '.change--button__approveAlways',...
in an array like
var strings = new Array('.change--button__approve', '.change--button__approveAlways', '.change--button__reject','.change--button__rejectAlways');
and use a for-loop to avoid code duplication:
for(int i=0; i<strings.length;i++){
$(this).find(strings[i]).click(function(){
...
}
}
your changing string 'once'/'always' also need an array if this basically works
(not completely sure)

Function being used, when it isn't a function?

Battle.CreateInputs = function(json) {
if (json.Battle.Continue !== undefined) {
$('#attackBox').css('display', 'none');
$('#Continue').mousedown(function(e) {
Battle.PlaySound('die')
Battle.Continue($(this).attr('continue'), e);
return false;
});
} else if (json.Battle.Captcha !== undefined) {
$('#attackBox').css('display', 'none');
$('#CaptchaForm').submit(function(e) {
Battle.PlaySound('captcha')
Battle.SubmitCaptcha($('#Captcha').val(), e);
return false;
});
} else if (json.Battle.Restart !== undefined) {
$('#attackBox').css('display', 'none');
$('#Restart').click(function(e) {
Battle.PlaySound('coin')
Battle.Restart($(this).attr('restart'), e);
return false;
});
} else {
$('#attackBox').css('display', 'inline-block');
$('input').mousedown(function(e) {
Battle.PlaySound('hit')
Battle.Move($(this).attr('post_code'), e);
return false;
});
}};
So, this is the code that I'm having problems with. I always receive the error "Battle.PlaySound is not a function". Here is a link to the Javascript and the code snippet that I was using.
My Code - http://pastebin.com/BnHLaYN3
Site Javascript - http://pastebin.com/0NcyWvGn
Battle.PlaySound is indeed not a function. As per your code:
Battle.PlaySound = {};
You are defining it as an object.
Should be something like this instead:
Battle.PlaySound = function(sound) {
//Do something with sound here.
};

JavaScript executes and works on MSVS but doesn't work when published

I am working with Lightswitch, and i am using this javascript to hide some buttons based on current user permissions. I am following this tutorial from MSDN:
https://msdn.microsoft.com/en-us/library/ff852062.aspx
This is my page
/// <reference path="~/GeneratedArtifacts/viewModel.js" />
myapp.Inicio.VisualizarAgenda_execute = function (screen) {
window.location = "../WebForms/Agenda.aspx";
};
myapp.Inicio.VisualizarCorridaExecutadaCompleta_execute = function (screen) {
// Write code here.
window.location = "../WebForms/CorridaExecutadaCorridaCompleta.aspx";
};
myapp.Inicio.ColetaMotoristaCorridas_execute = function (screen) {
window.location = "../WebForms/ColetaMotoristaCorrida.aspx";
};
myapp.Inicio.created = function (screen) {
//screen.getCanExecuteClientes().then(function success() {
// screen.findContentItem("ShowBrowseClientes").isVisible = true;
//}, function error() {
// screen.findContentItem("ShowBrowseClientes").isVisible = false;
//})
//screen.getCanExecuteMotoristas().then(function success() {
// screen.findContentItem("ShowBrowseMotoristas").isVisible = true;
//}, function error() {
// screen.findContentItem("ShowBrowseMotoristas").isVisible = false;
//})
//screen.getCanExecuteVeiculos().then(function success() {
// screen.findContentItem("ShowBrowseVeiculoes").isVisible = true;
//}, function error() {
// screen.findContentItem("ShowBrowseVeiculoes").isVisible = false;
//})
screen.getCanExecuteEnderecosCorrida().then(function success() {
screen.findContentItem("ShowBrowseEnderecoCorridas").isVisible = true;
}, function error() {
screen.findContentItem("ShowBrowseEnderecoCorridas").isVisible = false;
})
screen.getCanExecuteCorridas().then(function success() {
screen.findContentItem("ShowBrowseRotas").isVisible = true;
}, function error() {
screen.findContentItem("ShowBrowseRotas").isVisible = false;
})
screen.getCanExecuteCorridasAgendadas().then(function success() {
screen.findContentItem("ShowBrowseProgramacoesRota").isVisible = true;
}, function error() {
screen.findContentItem("ShowBrowseProgramacoesRota").isVisible = false;
})
screen.getCanExecuteCorridasExecutadas().then(function success() {
screen.findContentItem("ShowBrowseCorridaEsporadicas").isVisible = true;
screen.findContentItem("ShowBrowseCorridas").isVisible = true;
}, function error() {
screen.findContentItem("ShowBrowseCorridaEsporadicas").isVisible = false;
screen.findContentItem("ShowBrowseCorridas").isVisible = false;
})
screen.getIsMotoristaQuery().then(function success() {
screen.findContentItem("Cadastros").isVisible = false;
screen.findContentItem("Fechamento").isVisible = false;
screen.findContentItem("Relatorios").isVisible = false;
screen.findContentItem("Basicos").isVisible = false;
//screen.findContentItem("ShowBrowseColetaMotoristaCorridas").isVisible = true;
}, function error() {
screen.findContentItem("Cadastros").isVisible = true;
screen.findContentItem("Fechamento").isVisible = true;
screen.findContentItem("Relatorios").isVisible = true;
screen.findContentItem("Basicos").isVisible = true;
//screen.findContentItem("ShowBrowseColetaMotoristaCorridas").isVisible = false;
})
};
My problem is: When i am on Debug, it works perfect. When i deploy on my own computer, still works.
When i deploy on my Windows Server hosted on IIS , nothing happens.
Tested with both browsers(Local inside the server, and local on my development computer, which is not on the same network as the server)
if you are using id of controls by coping it from rendered html then yes it may not work when you deploy it.
you must use class selector in jquery to acheave this or find the real id of content item or you can use static id if you are using .net 4 and above.

Where in this code do I need to put 'return false'?

When I click on the 'slide-toggle' link, my url turns from mysite.com to mysite.com/#
I was told that I needed to put a 'return false' somewhere in here but I'm not sure where. Can someone kindly help me out?
$(document).ready(function() {
$('a#slide-up').click(function () {
$('.slide-container').slideUp(function(){
$('#slide-toggle').removeClass('active');
});
return false;
});
$('a#slide-toggle').click(function() {
var slideToggle = this;
if ($('.slide-container').is(':visible')) {
$('.slide-container').slideUp(function() {
$(slideToggle).removeClass('active');
});
}
else {
$('.slide-container').slideDown();
$(slideToggle).addClass('active');
}
});
});
It would be nicer not to use return false but to use event.preventDefault instead. You can put this at the very top of your event handler:
$('a#slide-toggle').click(function(e) { // note e added as the function's parameter
e.preventDefault();
var slideToggle = this;
if ($('.slide-container').is(':visible')) {
$('.slide-container').slideUp(function() {
$(slideToggle).removeClass('active');
});
}
else {
$('.slide-container').slideDown();
$(slideToggle).addClass('active');
}
});
This has the same effect as return false, but with the following advantages:
It is semantically more logical -- it does what it says
You can put it at the head of the function, so it is immediately obvious
You can have multiple exit points without having to ensure they are all return false
If any part of your code causes an error, the default action will still be prevented
like this:
$('a#slide-toggle').click(function() {
var slideToggle = this;
if ($('.slide-container').is(':visible')) {
$('.slide-container').slideUp(function() {
$(slideToggle).removeClass('active');
});
}
else {
$('.slide-container').slideDown();
$(slideToggle).addClass('active');
}
return false;
});
Probably you need to add the return false also in the $('a#slide-toggle').click() function
$(document).ready(function() {
$('a#slide-up').click(function () {
$('.slide-container').slideUp(function(){
$('#slide-toggle').removeClass('active');
});
return false;
});
$('a#slide-toggle').click(function() {
var slideToggle = this;
if ($('.slide-container').is(':visible')) {
$('.slide-container').slideUp(function() {
$(slideToggle).removeClass('active');
});
}
else {
$('.slide-container').slideDown();
$(slideToggle).addClass('active');
}
**return false;**
});
});
I think, it should be like this:
$('a#slide-toggle').click(function() {
var slideToggle = this;
if ($('.slide-container').is(':visible')) {
$('.slide-container').slideUp(function() {
$(slideToggle).removeClass('active');
});
}
else {
$('.slide-container').slideDown();
$(slideToggle).addClass('active');
}
return false;
});
You have one at the end of slide-up; add one to the end of slide-toggle.

How do I add a function to an element via jQuery?

I want to do something like this:
$('.dynamicHtmlForm').validate = function() {
return true;
}
$('.dynamicHtmlForm .saveButton').click(function() {
if (!$(this).closest('.dynamicHtmlForm').validate()) {
return false;
}
return true;
});
And then when I have a form of class dynamicHtmlForm, I want to be able to provide a custom validate() function:
$('#myDynamicHtmlForm').validate = function() {
// do some validation
if (there are errors) {
return false;
}
return true;
}
But I get this when I do this:
$(this).closest(".dynamicHtmlForm").validate is not a function
Is what I've described even possible? If so, what am I doing wrong?
Yes, it is technically possible. You will need to reference the element itself, however, and not the jQuery collection. This should work:
$('.dynamicHtmlForm').each(function (ix,o) {
o.validate = function() {
return true;
}
});
$('.dynamicHtmlForm .saveButton').click(function() {
if ($(this).closest('.dynamicHtmlForm')[0].validate()) {
return false;
}
return true;
}
jQuery.fn.validate = function(options) {
var defaults = {
validateOPtions1 : '',
validateOPtions2 : ''
};
var settings = $.extend({}, defaults, options);
return this.each(function() {
// you validation code goes here
});
};
$(document).ready(function() {
$('selector').click(function() {
$('some selector').validate();
// or if you used any options in your code that you
// want the user to enter. then you go :
$('some selector').validate({
validateOPtions1: 'value1',
validateOPtions2: 'value2'
});
});
});
You're not adding the function to the element, you're adding it to the jQuery wrapper around the element. Every time you pass a selector to jQuery, it will create a new wrapper for the found elements:
$('#myEl'); // gives a jQuery wrapper object
$('#myEl'); // creates another jQuery wrapper object
If you save the wrapped element to a variable and use that later, it would be a different story because you're accessing the saved jQuery wrapper object.
var dynamicHtmlForm = $('.dynamicHtmlForm');
dynamicHtmlForm.validate = function() {
return true;
}
$('.dynamicHtmlForm .saveButton').click(function() {
if (dynamicHtmlForm.validate()) {
return false;
}
return true;
}
You could also add the function directly to the element using
$('.dynamicHtmlForm')[0].validate = function () { return true; }
// and later...
if (!$(this).closest('.dynamicHtmlForm')[0].validate())
Or you could look at extending jQuery properly by writing a plugin.

Categories

Resources