pnotify prompt dialog not showing in an ember project - ember.js

I'm using the pnotify error and success dialogs without any trouble, but the prompt dialog doesn't want to show. I get a Uncaught TypeError: Cannot read property 'addClass' of undefined error.
Has anybody been successful in getting this to work?
jsbin: pnotify with ember

Here is a working example: http://jsbin.com/fuqoke/1/
So what is the problem. Well, Ember uses prototype extensions. This polyfills ECMAScript 5 array methods in browsers that do not implement them, adds convenience methods and properties to built-in arrays, and makes array mutations observable. The problem is that pnotify expects to work with normal oldschool javascript arrays. For example this code snippet where it wants to loop over an array:
...
for (var i in options.buttons) {
btn = options.buttons[i];
...
This loop will also iterate over the methods added to arrays by Ember (e.g. addObjects, firstObject,....)
So 2 ways to solve this:
1) You modify the pnotify code, and contribute it ;), with a more robust implementation to loop arrays
...
for (var i = 0; i < options.buttons.length; i++) {
btn = options.buttons[i];
...
or
...
for (var i in options.buttons) {
if(options.buttons.hasOwnProperty(i)){
btn = options.buttons[i];
...
2) You disable Ember's prototype extensions, which I don't recommend. Here you can find more info:http://emberjs.com/guides/configuring-ember/disabling-prototype-extensions/ but it will get you in a lot of trouble.
To be short it is definitely a bug in pnotify.

Related

SwiftUI: Why does ForEach need an ID?

Im using a ForEach loop in my SwiftUI View and I am getting strange warnings.
It works fine like this:
ForEach(0..<7) { i in
// do something
}
Then I changed 7 to a constant:
let numberOfElements = 7
ForEach(0..<numberOfElements) { i in
// do something
}
And got the following warning:
Non-constant range: argument must be an integer literal
I googled an found the following solution which works:
let numberOfElements = 7
ForEach(0..<numberOfElements, id:\.self) { i in
// do something
}
However, I have no idea why it works. Why do I have to give an ID to the ForEach loop, and what is the ID for?
ForEach(0..<numberOfElements) { i in
// do something
}
The reason why using the above ForEach init pops the using literal value warning is because SwiftUI doesn't expect to re-render anything when using the Range<Int> init method. This is a documented requirement / feature. The exceptions are the init methods with id:.
A hashable id matters in SwiftUI as well as in many other view-tree based frameworks like React is because these UI frameworks needs to use these ids to track updates for views inside the ForEach or any other "Container Views", to help the framework achieve usable performance. If you want to dig deeper, take a look at this WWDC video: Demystify SwiftUI.

Update an element that already has a plugin

Zurb Foundation 6.5.3
I have an accordion menu which needs to be updated via ajax after the initial page load. So initially the menu contains 2 items, then $(document).foundation(); is called. Later after an ajax response is received elements are added (and potentially removed/replaced) within the menu.
I would like to be able to re-use the same elements however, I can't update the plugin to re-style the changed elements. I've tried:
$("#my-menu").foundation(); which doesn't work and shows the error:
Tried to initialize accordion-menu on an element that already has a Foundation plugin.
Foundation.reflow(menu, 'accordion'); which doesn't work.
menu.foundation('reflow'); which doesn't work and shows the error:
Uncaught ReferenceError: We're sorry, 'reflow' is not an available method for AccordionMenu.
I have made it work by destroying and removing the existing menu, re-creating the whole thing, then calling $("#my-menu").foundation(); however this isn't ideal in my opinion.
I found that my issue was due to no one solution working in all 3 cases:
foundation has not yet been initialised
foundation is initialised and the entire element has been replaced since
foundation is initialised and the element has been updated since
Unless someone has a better answer, I solved using this approach:
// this can happen before, or after code creates the menu
$(document).foundation();
console.log("foundation run");
__foundationRun = true;
...
function foundationUpdate(el) {
if (__foundationRun) {
if (el.data('zfPlugin'))
// already initialised, update it
Foundation.reInit(el);
else
// new element, initialise it
el.foundation();
}
// else leave for foundation initialise
}
....
// ... do updates (modify or replace entirely) and then:
foundationUpdate($("#my-menu"));

Better errors with Ember

Is there a way to have clearer error messages when something is wrong with ember?
For exemple, I have this error 05:10:32,332 Error: Assertion Failed: A helper named 'eq' could not be found1 vendor.self-4fd4ab06f1f66c1cec72e1ec3a2c99328df792e46fb1fdcd0258c341b30a7c3b.js:24472:0
. This error is not the subject of the question, this is just an example.
I have no idea where is eq. The console indicated this function :
function EmberError() {
var tmp = Error.apply(this, arguments);
// Adds a `stack` property to the given error object that will yield the
// stack trace at the time captureStackTrace was called.
// When collecting the stack trace all frames above the topmost call
// to this function, including that call, will be left out of the
// stack trace.
// This is useful because we can hide Ember implementation details
// that are not very helpful for the user.
if (Error.captureStackTrace) {
Error.captureStackTrace(this, _emberMetalCore.default.Error);
}
// Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
for (var idx = 0; idx < errorProps.length; idx++) {
this[errorProps[idx]] = tmp[errorProps[idx]];
}
}
This is not related to my problem.
Obviouly, I searched eq in my code and I have no results. I suppose this is in a module but using grep is very ineffective.
Sometimes there is a stacktrace but its not very efficient too. To find an addon or the source in my code in a big vendor.js or myapp.js is not ideal.
Is there a better solution?
I think something in one of your addons or other third party code is using the ember-truth-helpers addon.
vendor.js typically contains third party code you've imported, not code that you've wrote.
As to the basic issue, it is really up to the maker of the third party code you've imported to document its dependencies and to ensure they are installed when you install that dependency. This really is not a failing of Ember itself, it has told you that there is no helper named eq and has given you the line number in the precompiled template where the eq was used. You can use the sources tab in Chrome to scroll to line 24472 in vendor.self-4fd4ab06f1f66c1cec72e1ec3a2c99328df792e46fb1fdcd0258c341b30a7c3b.js

emberjs get('lastObject') bug?

I'm looping through an array using Ember.Array#lastObject property:
while (last = this.get('clickViews.lastObject')) {
// perform some actions to last
this.get('clickViews').removeObject(last);
}
When all objects from the clickViews array have been removed, this.get('clickViews.lastObject') still returns an object. Is there something wrong with how I'm getting 'lastObject' or removing objects from array?
Maybe you should do it this way. See here for a working jsbin.
while (this.get('clickViews.lastObject') !== undefined) {
// perform some actions to last
this.get('clickViews').removeObject(this.get('clickViews.lastObject'));
}
Hope it helps.
This seems to be a cacheing problem with multiple versions of emberjs loaded within the browser window context, as similar to the answer to this question: emberjs getEach method does not work as expected
I resolved problem by clearing browser history and rails precompiled tmp files.

"Cannot call method 'destroy' of undefined" in arrayWillChange

I have what I think is a pretty standard array/template relationship setup, but when I push a new item into the array I get the above mentioned Cannot call method 'destroy' of undefined error in the arrayWillChange method of the Ember source:
for (idx = start + removedCount - 1; idx >= start; idx--) {
childView = childViews[idx];
if (removingAll) { childView.removedFromDOM = true; }
childView.destroy(); <-- childView is undefined
}
I have never had this issue before. This doesn't happen when I remove an item from the array. Only on addition. Below is a link for a JSBin where I tried to duplicate the issue. The error doesn't get thrown but the template doesn't update either.
http://jsbin.com/asemul/2
EDIT:
You're calling array.push instead of array.pushObject -- the latter is an Ember.js method that is binding aware, which means it will automatically update bindings for you. The handlebars template helper {{#each filters}} is a binding to the filters array of the controller, and the template needs to know to update when the underlying array is updated. push doesn't tell the binding to update, but pushObject does.
Here's a working example (all I did was change push to pushObject): http://jsbin.com/asemul/6/
This is a pretty common mistake -- usually, I find that if my templates aren't synchronized with the underlying object, it's because something's wrong with the bindings, so that's where I start looking.
END EDIT
I don't think you should be setting removedFromDOM directly -- try using childView.remove() followed by destroy().
I'm not sure what the context is, but have you looked at ContainerView or CollectionView? Both of those views have support for arrays of child views and may accomplish what you're looking to do both more robustly and with less code.