Ember Cli - Added Polyfill Internet Explorer Error Object Expected - ember.js

I have a problem and I don't see someone who has this kind of problem with this.
Basically I made a helper to format a date, it has some syntax of EcmaScript like let, or expoorts.
Its working in all the browsers except INTERNET EXPLORER, so I though ok its time to configure Polyfill, so I read the documentation to configure it with ember-cli-babel and I am not able to see the results as expected.
I have an ember app, with ember cli
DEBUG: -------------------------------
DEBUG: Ember : 2.14.1
DEBUG: jQuery : 2.2.4
DEBUG: -------------------------------
I include POLYFILL in my broccoli file like this
ember-cli
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
module.exports = function(defaults) {
var app = new EmberApp(defaults, {
'ember-cli-babel': {
includePolyfill: true
},
storeConfigInMeta: false,
minifyJS: {
enabled: false
},
minifyCSS: {
enabled: false
},
vendorFiles: {
'jquery.js': {
development: 'bower_components/jquery/dist/jquery.js',
production: false,
development: false
}
}
});
app.import('vendor/jquery.lumanetix.all.min.js');
return app.toTree();
};
I have a ember helper to format a date here it is:
import Ember from 'ember';
export function dateAuctionFormat(date/*, hash*/) {
let dateObj = new Date(date);
let monthName = getMonthName(dateObj.getUTCMonth());
let dayNumber = dateObj.getUTCDate();
dayNumber = dayNumber + formatDateNotation(dayNumber);
let dayName = getWeekDayName(dateObj.getDay());
let time = dateObj.toLocaleString('en-US', { hour: 'numeric', minute:'numeric', hour12: true });
return dayName + ' ' + dayNumber + ' ' + monthName + ' ' + time;
}
function getMonthName(date) {
let month = [];
month[0] = "Jan";
month[1] = "Feb";
month[2] = "March";
month[3] = "April";
month[4] = "May";
month[5] = "June";
month[6] = "July";
month[7] = "Aug";
month[8] = "Sept";
month[9] = "Oct";
month[10] = "Nov";
month[11] = "Dec";
return month[date];
}
function getWeekDayName(date) {
let weekday = new Array(7);
weekday[0] = "Sunday";
weekday[1] = "Monday";
weekday[2] = "Tuesday";
weekday[3] = "Wednesday";
weekday[4] = "Thursday";
weekday[5] = "Friday";
weekday[6] = "Saturday";
return weekday[date];
}
function formatDateNotation(d) {
if (d > 3 && d < 21) {
return 'th';
}
switch (d % 10) {
case 1: return "st";
case 2: return "nd";
case 3: return "rd";
default: return "th";
}
}
export default Ember.Helper.helper(dateAuctionFormat);
But when Internet Explorer 11 is rendering the site, I have an error in the debugger like this:
The error said Object Expected.
and you can see the error showing just after the line
export default App.extend({
// rootElement: '#listings-search'
});
So I don't know from where start, I try to modify a little bit, app.js, but no luck, also I tried to convert my ES6 code to ES5 with this converter:
https://babeljs.io/repl/
But of course it didn't work and also its not the idea.

I believe you need to add target to your targets config. You can use this list:
https://github.com/ai/browserslist#queries
This targets file is later used by Babel to determine which features are supported by browsers and this later affects transpiled JavaScript.

Related

IE9: store.find is failing

I can't seem to fetch new data in Internet Explorer 9. For the purpose of an example I test the store this way:
App.__container__.lookup('store:main').find('style')
The only error I receive is the following:
SCRIPT5022: Error: Assertion Failed: [object Object]
Does Ember-data works out of the box (without polyfills, ...) in Internet Explorer 9?
versions:
Ember: 1.9.1
Ember-data: 1.0.0-beta.12
Problem solved. When doing an AJAX request with jQuery, this normally happens through the XMLHttpRequest object.
On IE8-9, this object is not present, instead it uses XDomainRequest. The simplest fix for this is adding: https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest.
ember-data works out of the box with IE8+. According to this issue:
We've been supporting IE8 with our platform (built on Ember) for a
while now. Things I know:
shim/sham is not needed, it's polyfilled by Ember and Ember-Data.
You will need it if you want additional things like .bind() on a function, then you must prepend it to the vendor file (using Brocfile)
and we only include the shim for that purpose, not the sham
Solution Synthesis
Reason :
On IE8-9, this object is not present, instead it uses XDomainRequest.
Solution :
The issue is solved. When using an AJAX request with jQuery. Normally this is done through the XMLHttpRequest object. A simple fix would be using the Open-Source jQuery-ajaxTransport-XDomainRequest
Code : Adding :
jQuery-ajaxTransport-XDomainRequest.js
/*!
* jQuery-ajaxTransport-XDomainRequest - v1.0.4 - 2015-03-05
* https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest
* Copyright (c) 2015 Jason Moon (#JSONMOON)
* Licensed MIT (/blob/master/LICENSE.txt)
*/
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as anonymous module.
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// CommonJS
module.exports = factory(require('jquery'));
} else {
// Browser globals.
factory(jQuery);
}
}(function($) {
// Only continue if we're on IE8/IE9 with jQuery 1.5+ (contains the ajaxTransport function)
if ($.support.cors || !$.ajaxTransport || !window.XDomainRequest) {
return $;
}
var httpRegEx = /^(https?:)?\/\//i;
var getOrPostRegEx = /^get|post$/i;
var sameSchemeRegEx = new RegExp('^(\/\/|' + location.protocol + ')', 'i');
// ajaxTransport exists in jQuery 1.5+
$.ajaxTransport('* text html xml json', function(options, userOptions, jqXHR) {
// Only continue if the request is: asynchronous, uses GET or POST method, has HTTP or HTTPS protocol, and has the same scheme as the calling page
if (!options.crossDomain || !options.async || !getOrPostRegEx.test(options.type) || !httpRegEx.test(options.url) || !sameSchemeRegEx.test(options.url)) {
return;
}
var xdr = null;
return {
send: function(headers, complete) {
var postData = '';
var userType = (userOptions.dataType || '').toLowerCase();
xdr = new XDomainRequest();
if (/^\d+$/.test(userOptions.timeout)) {
xdr.timeout = userOptions.timeout;
}
xdr.ontimeout = function() {
complete(500, 'timeout');
};
xdr.onload = function() {
var allResponseHeaders = 'Content-Length: ' + xdr.responseText.length + '\r\nContent-Type: ' + xdr.contentType;
var status = {
code: 200,
message: 'success'
};
var responses = {
text: xdr.responseText
};
try {
if (userType === 'html' || /text\/html/i.test(xdr.contentType)) {
responses.html = xdr.responseText;
} else if (userType === 'json' || (userType !== 'text' && /\/json/i.test(xdr.contentType))) {
try {
responses.json = $.parseJSON(xdr.responseText);
} catch(e) {
status.code = 500;
status.message = 'parseerror';
//throw 'Invalid JSON: ' + xdr.responseText;
}
} else if (userType === 'xml' || (userType !== 'text' && /\/xml/i.test(xdr.contentType))) {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.async = false;
try {
doc.loadXML(xdr.responseText);
} catch(e) {
doc = undefined;
}
if (!doc || !doc.documentElement || doc.getElementsByTagName('parsererror').length) {
status.code = 500;
status.message = 'parseerror';
throw 'Invalid XML: ' + xdr.responseText;
}
responses.xml = doc;
}
} catch(parseMessage) {
throw parseMessage;
} finally {
complete(status.code, status.message, responses, allResponseHeaders);
}
};
// set an empty handler for 'onprogress' so requests don't get aborted
xdr.onprogress = function(){};
xdr.onerror = function() {
complete(500, 'error', {
text: xdr.responseText
});
};
if (userOptions.data) {
postData = ($.type(userOptions.data) === 'string') ? userOptions.data : $.param(userOptions.data);
}
xdr.open(options.type, options.url);
xdr.send(postData);
},
abort: function() {
if (xdr) {
xdr.abort();
}
}
};
});
return $;
}));

Objects from registerhelper in Handlebars.js / Browserify bundle not printing in Django app on some servers

I have a Django site that I'm deploying where I'm using Handlebars.js for templateing. I'm using Browserify to bundle the Javascript. I'm using registerhelper in Handlebars.js to iterate over some objects and print them in modals on click. A sample of this code is below.
I have my Django app deployed on a live dev server (Digital Ocean) and these text boxes are being populated without problem. When I pushed to the production server (university server) these text boxes are not getting populated. Otherwise the Django app is working fine on both live dev and production servers. There are no errors in the console.
The servers are similar but not totally the same. Both are running Ubuntu and Python 2.7 and have the same pip dependancies. We are using the same bundle.js from Browserify on both servers.
I don't know if this is a code problem or a dependency problem and it's driving me nuts because the deployment completely works on the live dev server. Any advice would be welcome.
Below is an example of my Handlebars code:
{{#countryListTitle attributes.works 'Projects'}}
<div class="row">
<div class="col-sm-12"><h3>Projects</h3></div>
{{#each attributes.works}}
{{#countryListContent attributes ../attributes.full_name 'Projects'}}
{{/countryListContent}}
{{/each}}
</div>
{{else}}
{{/countryListTitle}}
Below is an example of my related Javascript code:
registerHBHelpers: function(){
Handlebars.registerHelper('countryListTitle', function(works, needle, options) {
var yes = 0;
$.each(works, function(key, value) {
if (value.attributes.work_types[0].attributes.name == needle) {
yes = 1;
}
});
if(yes == 1) {
return options.fn(this);
} else {
return options.inverse(this);
}
});
Handlebars.registerHelper('countryListContent', function(attributes, full_name, type, options) {
var output = '';
var periodicals = '';
var publishers = '';
for(var i=0, l=attributes.work_types.length; i<l; i++) {
// add item name if the type is the type passed to the helper
if (attributes.work_types[i].attributes.name == type) {
output = output + '<div class="col-sm-12"><h4>' + attributes.title + '</h4></div>';
// add publication info if a publication
if (attributes.publicationinfo) {
var d = new Date(attributes.publicationinfo.date_published);
var month = d.getMonth() + 1; //Months are zero based
var year = d.getFullYear();
switch (month)
{
case 1:
month = 'January';
break;
case 2:
month = 'February';
break;
case 3:
month = 'March';
break;
case 4:
month = 'April';
break;
case 5:
month = 'May';
break;
case 6:
month = 'June';
break;
case 7:
month = 'July';
break;
case 8:
month = 'August';
break;
case 9:
month = 'September';
break;
case 10:
month = 'October';
break;
case 11:
month = 'November';
break;
case 12:
month = 'December';
break;
default:
month = '';
break;
}
if (attributes.publicationinfo.periodicals.length > 0) {
periodicals = attributes.publicationinfo.periodicals[0].trim() + ', ';
}
if (attributes.publicationinfo.publishers.length > 0) {
publishers = attributes.publicationinfo.publishers[0].trim() + ', ';
}
output = output + '<div class="col-sm-12"><p class="modal-fine-print">' + periodicals + publishers + 'Published ' + month + ' ' + year + '</p></div>';
// add buffer of no unordered lists will appear
if (attributes.topics.length === 0 && attributes.faculty.length === 0) {
output = output + '<div class="buffer"></div>';
}
}
if (attributes.faculty.length > 0) {
output = output + '<div class="col-sm-12"><p class="modal-list-first-element"><strong>Faculty</strong></p><p>';
for(var e=0, p=attributes.faculty.length; e<p; e++) {
if (attributes.faculty[e].attributes.home_page !== '') {
output = output + '' + attributes.faculty[e].attributes.full_name + '<br />';
} else {
output = output + '' + attributes.faculty[e].attributes.full_name + '<br />';
}
}
output = output + '</p></div>';
}
if (attributes.topics.length > 0) {
output = output + '<div class="col-sm-12"><p class="modal-list-first-element"><strong>Topics</strong></p><p>';
for(var h=0, m=attributes.topics.length; h<m; h++) {
output = output + attributes.topics[h].attributes.name + '<br />';
}
output = output + '</p></div>';
}
output = output + '<div class="buffer"></div>';
}
}
return new Handlebars.SafeString(output);
});
},
Lee
Figured this out - there was a change in an object name in the database. It was hard to debug, but simple problem in the end.

extending EmberDefaultResolver with Ember-App-Kit

I'm making a custom resolver based on the pattern below from Robin Ward [ video / 15sec]
which is a trick to have a mobile device look for "mob_template.hbs" first before loading "template.hbs"
App.Resolver = EmberDefaultResolver.extend({
resolveTemplate: function(parsedName){
var t = this._super(parsedName);
if App.mobileActive){
return this._super('mob_' + parsedName) || t;
}
return t;
}
});
However I'm using Ember App Kit, which uses a special version of the resolver:
I can't really tell what's going on in there or what I would need to do to produce similar functionality. Anyone have any idea?
I've tried something like this but it results in nothing being resolved:
var App = Ember.Application.extend({
//...
Resolver: Ember.DefaultResolver.extend({
resolve: function(fullName) {
var parsedName = this.parseName(fullName),
resolveMethodName = parsedName.resolveMethodName;
if (!(parsedName.name && parsedName.type)) {
throw new TypeError("Invalid fullName: `" + fullName + "`, must be of the form `type:name` ");
}
if (this[resolveMethodName]) {
if (window.screen_type == 'mobile'){
var resolved = this[resolveMethodName](parsedName + '_mobile');
} else{
var resolved = this[resolveMethodName](parsedName);
}
if (resolved) { return resolved; }
}
return this.resolveOther(parsedName);
},
})
});
Apparently parsedName is not a string of the template name in the EAK resolver, it has some props representing the template name though, parsedName.fullNameWithoutType being the one to target:
var CustomResolver = Resolver.extend({
resolveTemplate: function(parsedName){
var resolve = this._super(parsedName);
if (['foo','bar'].indexOf(window.special_prop) > -1){
var orig__parsedName_name = parsedName.name;
parsedName.name = parsedName.name + '_' + window.special_prop;
parsedName.fullName = parsedName.fullName + '_' + window.special_prop;
parsedName.fullNameWithoutType = parsedName.fullNameWithoutType + '_' + window.special_prop;
resolve = this._super(parsedName) || resolve;
}
return resolve;
} });
var App = Ember.Application.extend({ //... Resolver: CustomResolver });

How to disable deprecation warnings in Ember.js?

I've written up an application that uses Ember Data. It's passing all it's tests and running as expected, however, something is causing a repeated deprecation warning to be thrown into console.
I'd like to know how to disable these warnings in Ember.
You can just do Ember.deprecate = function(){} in your application.js file and that should disable ember deprecation warnings.
It's always good to consider deprecations, but if you want to just turn them off entirely add the following 2 lines to your main app.js file.
Ember.deprecate = function(){};
Ember.warn = function(i){};
My suggestion here, so you won't completely miss the deprecation warnings - they're there for a reason, right?
These are simplified versions of what deprecate would do, but logging to DEBUG (so you can filter them out easily) and without the stacktrace (for simplicity). They'll also not show repeated messages:
CoffeeScript:
Ember.deprecate = (->
already_shown = []
(msg, test, opt)->
return false if test
if already_shown.indexOf(msg) == -1
warning = "DEPRECATION: #{msg}"
warning += " See: #{opt.url}" if opt.url
console.debug warning
already_shown.push msg
)()
JS:
Ember.deprecate = (function() {
var already_shown = [];
return function (msg, test, opt) {
if (test) return false;
if (already_shown.indexOf(msg) === -1) {
var warning = 'DEPRECATION: ' + msg;
if (opt.url) {
warning += ' See: ' + opt.url;
}
console.debug(warning);
}
already_shown.push(msg);
};
})();
Modifed for Ember 2.3 version (thank's to igorsantos07)
const alreadyShownFactory = () => {
let alreadyShown = [];
return (msg, test, opt) => {
if (test)
return false;
if( alreadyShown.indexOf(msg) === -1 ) {
let warning = 'DEPRECATION: ' + msg;
if(opt && opt.url) {
warning += ' See: ' + opt.url;
}
console.warn(warning);
alreadyShown.push(msg);
}
};
};
Ember.deprecate = alreadyShownFactory();
Ember.warn = alreadyShownFactory();
//see https://guides.emberjs.com/v2.3.0/configuring-ember/handling-deprecations/
Ember.Debug.registerDeprecationHandler((() => {
let alreadyShown = [];
return (message, options, next) => {
if(alreadyShown.indexOf(message) === -1) {
next(message, options);
alreadyShown.push(message);
}
};
})());
For Ember 3.8 below code in app/initializers/deprecation.js worked for me. This disables the deprecations while running tests. You can modify according to your needs.
import { registerDeprecationHandler } from '#ember/debug';
export function initialize() {
registerDeprecationHandler((message, options, next) => {
if (options && options.until && options.until !== '2.0.0') {
return;
} else {
next(message, options);
}
});
}
export default { initialize };
Took this from the docs
If you're looking for this in Ember >=2.0.0, you have to change this in:
Ember.Logger.warn = () => {}
Ember.Logger.deprecate = () => {}

jQuery DatePicker calendar not returning correct month

I am soooo close here. I'm hoping a guru can help me with this last piece. I'm populating a jQuery DatePicker calendar with XML from an RSS feed. Upon clicking a highlighted date where there's an event, I'm creating a URL with a query string so I can display all the event for the clicked day. Everything is working... until I change the month by clicking previous or next month. My script will return the correct day, but is only returning the current month. For example, I navigate to May and click the 5th, my URL will be events.htm?month=june&day=5. Any ideas on why it will not return my selected month? Here's my code:
var data = $.ajax({
url: "news.xml",
type: "GET",
dataType: "xml",
async:false,
success: function(xml){
return xml;
}
} ).responseText;
$(document).ready(function() {
var events = getSelectedDates();
$("div.datepicker").datepicker({
beforeShowDay: function(date) {
var result = [true, '', null];
var matching = $.grep(events, function(event) {
return event.published.getDate() === date.getDate() && event.published.getMonth() === date.getMonth() && event.published.getFullYear() === date.getFullYear();
});
if (matching.length) {
result = [true, 'highlight', null];
}
return result;
},
onSelect: function(dateText) {
var date, selectedDate = new Date(dateText),
i = 0,
event = null;
while (i < events.length && !event) {
date = events[i].published;
if (selectedDate.getFullYear() === date.getFullYear() &&
selectedDate.getMonth() === date.getMonth() &&
selectedDate.getDate() === date.getDate()) {
event = events[i];
}
i++;
}
if (event) {
var eMonNum = event.published.getMonth();
var d = new Date();
var eMonNum = new Array();
eMonNum[0] = "january";
eMonNum[1] = "february";
eMonNum[2] = "march";
eMonNum[3] = "april";
eMonNum[4] = "may";
eMonNum[5] = "june";
eMonNum[6] = "july";
eMonNum[7] = "august";
eMonNum[8] = "september";
eMonNum[9] = "october";
eMonNum[10] = "november";
eMonNum[11] = "december";
var eMon = eMonNum[d.getMonth()];
var eDay = event.published.getDate();
window.location = "events.htm?month="+eMon+"&day="+eDay;
}
}
});
});
function getSelectedDates() {
return $(data).find('entry').map(function() {
return {
title: $('title', this).text(),
published: new Date($('published', this).text())
};
}).get();
}
Found the problem, when you copied this list from a resource, you forgot to replace the variables.
CHANGE (at the end of month list)
var eMon = eMonNum[d.getMonth()];
TO:
var eMon = eMonNum[event.published.getMonth()];
All I did was get rid of the bad variable and reassigned your month variable to the one you used for the day. You can also remove the declaration of the d variable, as you will not need it.
Best of luck!