Template helpers not working after meteor update - javascript

So I updated my Meteor from v0.8, to latest 1.0, and one of the issues I encountered was that normal template helpers stopped working, as in:
This used to work:
Template.allCustomers.helpers({
getAllCustomers: function(filter) {
return Customers.find(filter, {sort: {registered: -1 } });
},
when called like:
Template.allCustomers.getAllCustomers();
..but after the update it didnt. So I looked it up into the Template.allCustomers object, and found that by calling it like this it works:
Template.allCustomers.__helpers.get("getAllCustomers")()
So my question is, is this the actual intention? Seems like it was uselessly complicated. I tried to search documentation on templating changes but could not locate and understand:
why was this change made
where is the improvement.
Thanks,

Related

react external javascript integration

I'm tring to merge 2 projects i found:
https://github.com/danxfisher/MeetEasier
and
this page https://tympanus.net/Development/Interactive3DMallMap/
i've done the changes in the react project meeteasier and included the html parts from interactivemallmap(with my little react abd nodejs knowledge) . I have problems on calling the javascript from main.js(interactivemallmap).
Here is the problem:
The first time i load the page with the chromedev i see that in the main.js it gets the values but when i recall the functions that values are null:
original main.js start like this and dot work:
;(function(window) {
...
mall = document.querySelector('.mall'),
...
pins = [].slice.call(mallLevelsEl.querySelectorAll('.map__space')),
....
pins.forEach(function(pin) {
var contentItem = contentEl.querySelector('.content__item[data- space="' + pin.getAttribute('data-space') + '"]');
pin.addEventListener('mouseenter', function() {
//if( !isOpenContentArea ) {
classie.add(contentItem, 'content__item--hover');
//}
});
....
})(window);
i've tried with the $(document).ready(function(){ instead of ;(function(window) {
but it is not working or better: in the first page load the it gets its value, but after when i pass over with the mouse and the event mouseenter triggers all the values are undefined
I think this is not the right approach but how do i make it work?
I do not have enough code to fully understand what is going on, but seeing that you're trying to merge two big projects with different codebases, if I were you I should take it slow, and take some steps back.
Your problem:
The main problem is that, to use React, you should first have a fundemental understanding of what it is doing under the hood.
You're trying to implement jQuery (a DOM library) with React, however, this will not work this easily, because React works with something that's called a virtual DOM, and it does not have access to the regular DOM nodes unless specifically ordered to do so (using findDOMNode from the react-dom package handles this for example).
What you should do:
Please read the docs first:
https://reactjs.org/docs/hello-world.html
Then, after you understand React, try implementing the SVG maps in it, step by step.
Just a small insight:
Rendering SVG in your render method, or try rebuilding it with D3 (https://d3js.org/) for example, just a suggestion on how to handle complex SVG.
You should handle most logic that's from main.js in the componentDidMount lifecycle, assuming you're going to need to access the map nodes.

Building a conditional Ember helper

I'm trying to build a new conditional helper for my Ember application.
Is important mention that I'm using Ember 1.10.1 that uses Handlebars 2.0 and I can't upgrade it, would be great solving the problem with this version of Ember.
Before writing here I tried different solutions and debugged the Ember code a lot, I'm near to the solution but probably I'm missing something.
First of all, I tried with the following approach reading the Handlebar documentation:
Ember.Handlebars.registerHelper('helperName', function(conditional, options) {
if(conditional) {
return options.fn(this);
} else {
return options.inverse(this);
}
});
And here the template:
{{#helperName booleanCondition}}
print true
{{else}}
print false
{{/helperName}}
Everything worked fine calling the fn function but the inversion function (used to render the template of the else branch) was actually an object instead of a function.
Then I started debugging the Ember code and I tried to follow the same approach that Ember uses with the if helper, so I ended up with the following:
Ember.Handlebars.registerHelper('helperName', function(condition, options) {
var permission = Ember.Object.extend({
can: Ember.computed(function() {
return condition;
})
}).create();
Ember.Handlebars.helpers.boundIf.helperFunction.call(this, ["can"], permission, options, options.data.buffer);
});
can is the property bound to the if, used to change the template if the property changes, since we are using the boundIf version of the if (that does what I just said).
The problem of this solution, that imho could be the nearest to be correct, is that the property is not computed correctly and the helper prints always the false value.
I debugged really a lot without making it working, so any help would be very appreciated and I hope this could be useful for someone else as well.
If what you're trying to do is build a conditional approach that supports authorization questions, you should take a look at ember-can. It is an Ember-CLI addon (whereas it looks like you are doing globals) but older versions worked with Ember 1.10. You should be able to reference what they do there and pull it in on your setup
The good news is you are on Ember 1.10!
This means you have subexpressions. And its simple to create a bound non-block helper:
Ember.HTMLBars._registerHelper('foo', function(bar) {
return bar == 'bar';
});
To use it as a block helper combine it with the {{#if}} helper:
{{#if (foo model)}}
in if
{{else}}
in else
{{/if}}

Custom Unobtrusive Validation Method Not Firing as Per Documentation

I've been attempting to implement a ASP.NET MVC custom validation method. Tutorials I've used such as codeproject explain that you add data-val-customname to the element. Then jQuery.validate.unobtrusive.js then uses the third segment of the attribute
data-val-<customname>
as the name of the rule, as shown below.
$.validator.addMethod('customname', function(value, element, param) {
//... return true or false
});
However I just can't get the customname method to fire. By playing around I have been able to get the below code to work, but according to all the sources I've read Unobtrusive validation should not work like this.
$.validator.addMethod('data-val-customname', function(value, element, param) {
//... return true or false
});
I've posted an example of both methods
jsfiddle example
Any help would be much appreciated
I've updated my question hopefully to make clearer.
I have finally found got there in the end, but still feels like too much hard work and therefore I've probably got something wrong. Initial I was scuppered by a bug in Chrome Canary 62 which refused to allow the adding of a custom method.
My next issue was having to load jQuery, jQuery.validate and jQuery.validate.unobtrusive in the markup and then isolate javascript implementation in a ES6 class. I didn't want to add my adaptors before $().ready() because of my class structure and loading of the app file independent of jQuery. So I had to force $.validator.unobtrusive.parse(document);.
Despite this I was still having issues and finally debugged the source code and found that an existing validator information that is attached to the form was not merging with the updated parsed rules, and essentially ignoring any new adaptors added.
My final work around and admit feels like I've done too much, was to destroy the initial validation information before my forced re-parse.
Here is the working jsfiddle demo
Here is some simplified code
onJQueryReady() {
let formValidator = $.data(document.querySelector('form'), "validator" );
formValidator.destroy();
$.validator.unobtrusive.adapters.add("telephone", [], function (options) {
options.rules['telephone'] = {};
options.messages['telephone'] = options.message;
});
$.validator.unobtrusive.parse(document);
$.validator.addMethod("telephone", this.handleValidateTelephoneNumber);
}

Querying the DOM in Windows 8 Apps from within a method

I'm struggling with this even after reading the MSDN documentation and the following online guides:
Codefoster
Stephen Walter
I think my problem is easy to fix and that I just am thinking about something in the wrong way. Basically I am querying my web service and on success running the following method. I am then trying to bind the result to my listview. For now I am using a hardcoded value publicMembers.itemlistwhich has been declared at the top of the document just to make sure I can actually bind to the list before doing it with my query results. Ignore line 2 for now.
Success Method:
_lookUpSuccess: function xhrSucceed(Result) {
var response = JSON.parse(Result.responseText);
listView = document.querySelector("#termTest");
ui.setOptions(listView, {
itemDataSource: publicMembers.itemList,
itemTemplate: document.querySelector(".itemtemplate"),
})
},
Now, instead of using document.querySelector, I have also tried with WinJS.Utilities.id and WinJS.Utilities.query, neither of which worked either. This doesn't break my code and introduce an error but it doesn't bind to the listview either so I think I have an issue in querying the right DOM element. However exactly the same code does work if I add it to the top of the script, it is only when I place it in this method that it stops working.
EDIT: Also to clarify, when I debug publicMembers.itemList is storing the values I expect them to be.
Please point out if I have explained things poorly and I will try and improve my question.
Thanks.
I haven't used WinJS.UI.setOptions, but rather this other way of setting the data source. Can you see if it works?
_lookUpSuccess: function xhrSucceed(result) {
var response = JSON.parse(result.responseText);
listView = document.querySelector("#termTest");
listView.winControl.itemDataSource = publicMembers.itemList;
},
This would assume you're defining the itemTemplate as part of the data-win-options attribute of your ListView's HTML element. You could also probably just do listView.winControl.itemTemplate = document.querySelector(".itemtemplate") if you prefer to set it programmatically.

How to inject some JS code after every remote call in Rails 3

So I'm using timeago plugin in my Rails 3 app, wrapping it within this function (note than the timeout just keeps the timeago strings updated to the minute at every moment):
function doTimeago() {
$('.timeago').each(function() {
var $this = $(this);
if ($this.data('active')!='yes') {
$this.timeago().data('active','yes');
}
});
}
And then in my application.js
$(function() {
doTimeago();
}
This works great until I load some elements using remote calls. I researched a bit and found no working solution. I'm not happy adding livequery plugin as suggested in this question since it seems deprecated.
I was thinking of adding this JS code to the end of every js.erb file in my app, but it feels really duplicated and nasty.
doTimeago();
Question part 1: ¿Is there an easy way to inject that code after every js.erb execution?
Question part 2: ¿How do I achieve my primary goal of having ajaxy loaded elements work with timeago?
You can bind it to ajaxComplete event, like this:
$(document).on('ajaxComplete', function(){
do_timeago();
});
BTW, I didn't understand your timeout in do_timeago function. Also, JS best practices are a bit different than ruby ones, consider rename your function to something like doTimeago.
Hope it helps.

Categories

Resources