Loop through data layer and display dynamic contentFaster way to render XML (10MB) file, loop the content and...

What to wear for invited talk in Canada

Domain expired, GoDaddy holds it and is asking more money

Where else does the Shulchan Aruch quote an authority by name?

Can the Produce Flame cantrip be used to grapple, or as an unarmed strike, in the right circumstances?

Lied on resume at previous job

Why airport relocation isn't done gradually?

Can I find out the caloric content of bread by dehydrating it?

What causes the sudden spool-up sound from an F-16 when enabling afterburner?

What does it exactly mean if a random variable follows a distribution

Unbreakable Formation vs. Cry of the Carnarium

What do the Banks children have against barley water?

What is the meaning of "of trouble" in the following sentence?

A poker game description that does not feel gimmicky

Why do we use polarized capacitors?

Manga about a female worker who got dragged into another world together with this high school girl and she was just told she's not needed anymore

Ideas for 3rd eye abilities

LWC and complex parameters

Information to fellow intern about hiring?

Is "plugging out" electronic devices an American expression?

How to move the player while also allowing forces to affect it

If a centaur druid Wild Shapes into a Giant Elk, do their Charge features stack?

Why doesn't a const reference extend the life of a temporary object passed via a function?

How to manage monthly salary

What is GPS' 19 year rollover and does it present a cybersecurity issue?



Loop through data layer and display dynamic content


Faster way to render XML (10MB) file, loop the content and display outputGet and display employee time clock dataSpeed up loop through JSONUser generated filter and contentDisplay tabular data with jQuery Datatables pluginForm submit and data displayInput, display and search company datajQuery toggle class and content on click of linkDisplay Sensor Data to WebData Layer Object Getter and Setter by Path






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ margin-bottom:0;
}







1












$begingroup$


The purpose of the pricingTest object is to grab pricing information from the dataLayer on the page and render content blocks accordingly. My goal in posting this is to hopefully receive some feedback in regards to the design pattern used and performance of the code, or anything else you see as worth pointing out. For example:




  1. Is my use of a constructor implemented in a standard and acceptable way?

  2. Is there anything that can be done to optimize the performance of this code?


I've been learning JavaScript for about a year and it is my first language.



// source of the data and details to the best of my understanding
// this is loaded in the <head> of each different page
// each page can have a different combination of 'levelsofcare'
// the 'care_type_id' of 'AL' can have a different 'name' depending on geographic location
// 'AllCareIncluded' is set for individual 'care' levels, excluding 'IL'
// 'Medicaid' and 'SemiPrivateAvailable' are each set at a global level
// 'care_type_category' and 'sort_order' are being ignored for this task
<script type="text/javascript">
var digitalData = {
page: {
pageInfo: {}
}
};
</script>
<script type="text/javascript">
digitalData.page.pageInfo['levelsOfCare'] = [{"care_type_id":"MC","name":"Memory Care","care_type_category":"resident","sort_order":3},{"care_type_id":"AL","name":"Personal Care Home","care_type_category":"resident","sort_order":4},{"care_type_id":"IL","name":"Independent Living","care_type_category":"resident","sort_order":5}];
digitalData.page.pageInfo['pricingIL'] = '2600';
digitalData.page.pageInfo['pricingAL'] = '5817';
digitalData.page.pageInfo['pricingMC'] = '8558';
digitalData.page.pageInfo['pricingAllCareIncludedAL'] = '0';
digitalData.page.pageInfo['pricingAllCareIncludedMC'] = '1';
digitalData.page.pageInfo['pricingMedicaid'] = '0';
digitalData.page.pageInfo['pricingSemiPrivateAvailable'] = '1';
</script>
// end source of the data

var pricingTest = {
careLevels: digitalData.page.pageInfo.levelsOfCare,
ilPrice: digitalData.page.pageInfo.pricingIL,
alPrice: digitalData.page.pageInfo.pricingAL,
mcPrice: digitalData.page.pageInfo.pricingMC,
ilCareIncluded: '0',
alCareIncluded: digitalData.page.pageInfo.pricingAllCareIncludedAL || '0',
mcCareIncluded: digitalData.page.pageInfo.pricingAllCareIncludedMC || '0',
medicaid: digitalData.page.pageInfo.pricingMedicaid,
semiPrivate: digitalData.page.pageInfo.pricingSemiPrivateAvailable,
iconLinkTails: {
MC: 'mc-path-ending',
AL: 'al-path-ending',
IL: 'il-path-ending'
},
descriptions: {
MC: [
'MC Description A',
'MC Description B'
],
AL: [
'AL Description A',
'AL Description B'
],
IL: [
'IL Description A',
'IL Description B'
]
},
svgLogo: '<svg class="pricing-info__item--leaf" height="82px" version="1.1" viewbox="0 0 50 82" width="50px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">...</svg>',
checkLargeAlMcPriceGap: function () {
if (pricingTest.mcPrice - pricingTest.alPrice > 1500) {
console.log("MC Price: " + pricingTest.mcPrice + " AL Price: " + pricingTest.alPrice + " Difference is greater than 1500");
return true;
}
},
checkIfMedicaid: function () {
if (pricingTest.medicaid === '1') {
return '<p class="pricing-info__footer-medicaid"><span class="fa fa-dollar"></span>Medicaid accepted at this community</p>';
} else {
return '';
}
},
checkIfSemiPrivate: function () {
if (pricingTest.semiPrivate === '1') {
return '<p class="pricing-info__footer-semiprivate"><span class="fa fa-arrow-down"></span>Semiprivate rooms available at a lower cost</p>';
} else {
return '';
}
},
init: function () {
// polyfill Array.prototype.map
if(!Array.prototype.map){Array.prototype.map=function(callback){var T,A,k;if(this==null){throw new TypeError("this is null or not defined");}var O=Object(this);var len=O.length>>>0;if(typeof callback!=="function"){throw new TypeError(callback+" is not a function");}if(arguments.length>1){T=arguments[1];}A=new Array(len);k=0;while(k<len){var kValue,mappedValue;if(k in O){kValue=O[k];mappedValue=callback.call(T,kValue,k,O);A[k]=mappedValue;}k++;}return A;};}
// end polyfill
function getYesterdaysDate() {
var today = new Date();
var yesterday = new Date(today);
yesterday.setDate(today.getDate() - 1);
var dd = yesterday.getDate();
var mm = yesterday.getMonth() + 1;
var yyyy = yesterday.getFullYear();
if (dd < 10) { dd = '0' + dd; } if (mm < 10) { mm = '0' + mm; }
yesterday = mm + '/' + dd + '/' + yyyy;
return '<span class="pricing-info__date">As of ' + yesterday + '</span>';
}
var outerAnchor = document.querySelector('.communityTwoColumn');
var communityName = document.querySelector('h1[itemprop="name"]').textContent;
outerAnchor.insertAdjacentHTML("afterEnd", '<div id="pricingInfo"><div class="pricing-info retain retain--padded"><div class="headline3 text-center">Pricing for ' +
communityName +
getYesterdaysDate() +
'</div><div class="flex-row row" id="pricing-info-row"></div><div class="pricing-info__footer text-center"><div class="pricing-info__footer-community-specials">' +
pricingTest.checkIfMedicaid() +
pricingTest.checkIfSemiPrivate() + '</div><p class="pricing-info__footer--heading">For more details on pricing and availability</p><div class="pricing-info__footer--ctas"><div>Call <a class="pricing-info__footer--phone" href="tel:800-350-3800">800-350-3800</a></div><div><span>or</span></div><div><a class="pricing-info__footer--form-link hidden-md hidden-lg" onclick="app.communityCTAContactForm.openMobileScrollandShowLogin(event, this)" href="#">Complete the form above</a><a class="pricing-info__footer--form-link hidden-xs hidden-sm" onclick="functionName(event)" href="#">Complete the form above</a></div></div><p class="pricing-info__footer--disclaimer"><span class="pricing-info__footer--disclaimer-asterisk">*</span>Lorem ipsum dolor sit amet.</p></div></div></div>'
);
function getCareName(item) {
var careProfile = [item.care_type_id, item.name];
if (item.care_type_id === "IL") {
careProfile.push(
pricingTest.iconLinkTails.IL,
pricingTest.descriptions.IL[0],
parseInt(pricingTest.ilPrice, 10).toLocaleString("en"),
pricingTest.ilCareIncluded,
pricingTest.descriptions.IL[1]
);
} else if (item.care_type_id === "AL") {
careProfile.push(
pricingTest.iconLinkTails.AL,
pricingTest.descriptions.AL[0],
parseInt(pricingTest.alPrice, 10).toLocaleString("en"),
pricingTest.alCareIncluded,
pricingTest.descriptions.AL[1]
);
} else if (item.care_type_id === "MC") {
careProfile.push(
pricingTest.iconLinkTails.MC,
pricingTest.descriptions.MC[0],
parseInt(pricingTest.mcPrice, 10).toLocaleString("en"),
pricingTest.mcCareIncluded,
pricingTest.descriptions.MC[1]
);
}
return careProfile;
}
var careProfiles = pricingTest.careLevels.map(getCareName);
var innerAnchor = document.getElementById('pricing-info-row');
// Constructor
function Block(careId, careName, iconLinkTail, descriptionA, price, careIncluded, descriptionB) {
this.careId = careId;
this.careName = careName;
this.iconLinkTail = iconLinkTail;
this.descriptionA = descriptionA;
this.price = price;
this.careIncluded = careIncluded;
this.descriptionB = descriptionB;
this.renderPrice = function () {
if (this.price === "NaN" || (this.careId === "MC" && pricingTest.checkLargeAlMcPriceGap() === true)) {
return 'Call for Pricing';
} else {
return '<p class="pricing-info__item--price-label">– Base Rental Rate –</p><p>Starting at <span id="itemPrice">$' + this.price + '</span><span class="pricing-info__item--price-asterisk">*</span>per month</p>';
}
};
this.renderCareIncludedPill = function () {
if (this.careIncluded === '1') {
return '<div class="pricing-info__item--care-included"><span class="fa fa-heart"></span>Care Included*</div>';
} else {
return '';
}
};
innerAnchor.insertAdjacentHTML(
"beforeEnd",
'<div class="col-md-4 text-center pricing-info__care-included-' +
this.careIncluded +
'" id="pricingBlock' +
this.careId +
'"><div class="pricing-info__item"><img src="https://www.domain.com/content/path/path/en/icons/' +
this.iconLinkTail +
'-icon.svg" alt="' +
this.careName +
' Icon" height="84px" width="84px" /><p class="pricing-info__item--heading">' +
this.careName +
'</p><p class="pricing-info__item--description">' +
this.descriptionA +
'</p><div class="pricing-info__item--price-footer"><div class="pricing-info__item--price">' +
this.renderPrice() +
'</div><div class="pricing-info__item--footer"><p>' +
this.descriptionB +
'</p>' +
pricingTest.svgLogo +
'</div></div></div>' +
this.renderCareIncludedPill() + '</div>'
);
}
// pass each careProfile array as a parameter to the constructor
for (var i = 0; i < careProfiles.length; i++) { Block.apply({}, careProfiles[i]); }
}
};
$(document).ready(function(){ pricingTest.init(); });









share|improve this question









New contributor




jman25 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$








  • 2




    $begingroup$
    Welcome to Code Review! It would be a good idea to explain the source of the data and provide a sample of what that data looks like.
    $endgroup$
    – 200_success
    2 days ago


















1












$begingroup$


The purpose of the pricingTest object is to grab pricing information from the dataLayer on the page and render content blocks accordingly. My goal in posting this is to hopefully receive some feedback in regards to the design pattern used and performance of the code, or anything else you see as worth pointing out. For example:




  1. Is my use of a constructor implemented in a standard and acceptable way?

  2. Is there anything that can be done to optimize the performance of this code?


I've been learning JavaScript for about a year and it is my first language.



// source of the data and details to the best of my understanding
// this is loaded in the <head> of each different page
// each page can have a different combination of 'levelsofcare'
// the 'care_type_id' of 'AL' can have a different 'name' depending on geographic location
// 'AllCareIncluded' is set for individual 'care' levels, excluding 'IL'
// 'Medicaid' and 'SemiPrivateAvailable' are each set at a global level
// 'care_type_category' and 'sort_order' are being ignored for this task
<script type="text/javascript">
var digitalData = {
page: {
pageInfo: {}
}
};
</script>
<script type="text/javascript">
digitalData.page.pageInfo['levelsOfCare'] = [{"care_type_id":"MC","name":"Memory Care","care_type_category":"resident","sort_order":3},{"care_type_id":"AL","name":"Personal Care Home","care_type_category":"resident","sort_order":4},{"care_type_id":"IL","name":"Independent Living","care_type_category":"resident","sort_order":5}];
digitalData.page.pageInfo['pricingIL'] = '2600';
digitalData.page.pageInfo['pricingAL'] = '5817';
digitalData.page.pageInfo['pricingMC'] = '8558';
digitalData.page.pageInfo['pricingAllCareIncludedAL'] = '0';
digitalData.page.pageInfo['pricingAllCareIncludedMC'] = '1';
digitalData.page.pageInfo['pricingMedicaid'] = '0';
digitalData.page.pageInfo['pricingSemiPrivateAvailable'] = '1';
</script>
// end source of the data

var pricingTest = {
careLevels: digitalData.page.pageInfo.levelsOfCare,
ilPrice: digitalData.page.pageInfo.pricingIL,
alPrice: digitalData.page.pageInfo.pricingAL,
mcPrice: digitalData.page.pageInfo.pricingMC,
ilCareIncluded: '0',
alCareIncluded: digitalData.page.pageInfo.pricingAllCareIncludedAL || '0',
mcCareIncluded: digitalData.page.pageInfo.pricingAllCareIncludedMC || '0',
medicaid: digitalData.page.pageInfo.pricingMedicaid,
semiPrivate: digitalData.page.pageInfo.pricingSemiPrivateAvailable,
iconLinkTails: {
MC: 'mc-path-ending',
AL: 'al-path-ending',
IL: 'il-path-ending'
},
descriptions: {
MC: [
'MC Description A',
'MC Description B'
],
AL: [
'AL Description A',
'AL Description B'
],
IL: [
'IL Description A',
'IL Description B'
]
},
svgLogo: '<svg class="pricing-info__item--leaf" height="82px" version="1.1" viewbox="0 0 50 82" width="50px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">...</svg>',
checkLargeAlMcPriceGap: function () {
if (pricingTest.mcPrice - pricingTest.alPrice > 1500) {
console.log("MC Price: " + pricingTest.mcPrice + " AL Price: " + pricingTest.alPrice + " Difference is greater than 1500");
return true;
}
},
checkIfMedicaid: function () {
if (pricingTest.medicaid === '1') {
return '<p class="pricing-info__footer-medicaid"><span class="fa fa-dollar"></span>Medicaid accepted at this community</p>';
} else {
return '';
}
},
checkIfSemiPrivate: function () {
if (pricingTest.semiPrivate === '1') {
return '<p class="pricing-info__footer-semiprivate"><span class="fa fa-arrow-down"></span>Semiprivate rooms available at a lower cost</p>';
} else {
return '';
}
},
init: function () {
// polyfill Array.prototype.map
if(!Array.prototype.map){Array.prototype.map=function(callback){var T,A,k;if(this==null){throw new TypeError("this is null or not defined");}var O=Object(this);var len=O.length>>>0;if(typeof callback!=="function"){throw new TypeError(callback+" is not a function");}if(arguments.length>1){T=arguments[1];}A=new Array(len);k=0;while(k<len){var kValue,mappedValue;if(k in O){kValue=O[k];mappedValue=callback.call(T,kValue,k,O);A[k]=mappedValue;}k++;}return A;};}
// end polyfill
function getYesterdaysDate() {
var today = new Date();
var yesterday = new Date(today);
yesterday.setDate(today.getDate() - 1);
var dd = yesterday.getDate();
var mm = yesterday.getMonth() + 1;
var yyyy = yesterday.getFullYear();
if (dd < 10) { dd = '0' + dd; } if (mm < 10) { mm = '0' + mm; }
yesterday = mm + '/' + dd + '/' + yyyy;
return '<span class="pricing-info__date">As of ' + yesterday + '</span>';
}
var outerAnchor = document.querySelector('.communityTwoColumn');
var communityName = document.querySelector('h1[itemprop="name"]').textContent;
outerAnchor.insertAdjacentHTML("afterEnd", '<div id="pricingInfo"><div class="pricing-info retain retain--padded"><div class="headline3 text-center">Pricing for ' +
communityName +
getYesterdaysDate() +
'</div><div class="flex-row row" id="pricing-info-row"></div><div class="pricing-info__footer text-center"><div class="pricing-info__footer-community-specials">' +
pricingTest.checkIfMedicaid() +
pricingTest.checkIfSemiPrivate() + '</div><p class="pricing-info__footer--heading">For more details on pricing and availability</p><div class="pricing-info__footer--ctas"><div>Call <a class="pricing-info__footer--phone" href="tel:800-350-3800">800-350-3800</a></div><div><span>or</span></div><div><a class="pricing-info__footer--form-link hidden-md hidden-lg" onclick="app.communityCTAContactForm.openMobileScrollandShowLogin(event, this)" href="#">Complete the form above</a><a class="pricing-info__footer--form-link hidden-xs hidden-sm" onclick="functionName(event)" href="#">Complete the form above</a></div></div><p class="pricing-info__footer--disclaimer"><span class="pricing-info__footer--disclaimer-asterisk">*</span>Lorem ipsum dolor sit amet.</p></div></div></div>'
);
function getCareName(item) {
var careProfile = [item.care_type_id, item.name];
if (item.care_type_id === "IL") {
careProfile.push(
pricingTest.iconLinkTails.IL,
pricingTest.descriptions.IL[0],
parseInt(pricingTest.ilPrice, 10).toLocaleString("en"),
pricingTest.ilCareIncluded,
pricingTest.descriptions.IL[1]
);
} else if (item.care_type_id === "AL") {
careProfile.push(
pricingTest.iconLinkTails.AL,
pricingTest.descriptions.AL[0],
parseInt(pricingTest.alPrice, 10).toLocaleString("en"),
pricingTest.alCareIncluded,
pricingTest.descriptions.AL[1]
);
} else if (item.care_type_id === "MC") {
careProfile.push(
pricingTest.iconLinkTails.MC,
pricingTest.descriptions.MC[0],
parseInt(pricingTest.mcPrice, 10).toLocaleString("en"),
pricingTest.mcCareIncluded,
pricingTest.descriptions.MC[1]
);
}
return careProfile;
}
var careProfiles = pricingTest.careLevels.map(getCareName);
var innerAnchor = document.getElementById('pricing-info-row');
// Constructor
function Block(careId, careName, iconLinkTail, descriptionA, price, careIncluded, descriptionB) {
this.careId = careId;
this.careName = careName;
this.iconLinkTail = iconLinkTail;
this.descriptionA = descriptionA;
this.price = price;
this.careIncluded = careIncluded;
this.descriptionB = descriptionB;
this.renderPrice = function () {
if (this.price === "NaN" || (this.careId === "MC" && pricingTest.checkLargeAlMcPriceGap() === true)) {
return 'Call for Pricing';
} else {
return '<p class="pricing-info__item--price-label">– Base Rental Rate –</p><p>Starting at <span id="itemPrice">$' + this.price + '</span><span class="pricing-info__item--price-asterisk">*</span>per month</p>';
}
};
this.renderCareIncludedPill = function () {
if (this.careIncluded === '1') {
return '<div class="pricing-info__item--care-included"><span class="fa fa-heart"></span>Care Included*</div>';
} else {
return '';
}
};
innerAnchor.insertAdjacentHTML(
"beforeEnd",
'<div class="col-md-4 text-center pricing-info__care-included-' +
this.careIncluded +
'" id="pricingBlock' +
this.careId +
'"><div class="pricing-info__item"><img src="https://www.domain.com/content/path/path/en/icons/' +
this.iconLinkTail +
'-icon.svg" alt="' +
this.careName +
' Icon" height="84px" width="84px" /><p class="pricing-info__item--heading">' +
this.careName +
'</p><p class="pricing-info__item--description">' +
this.descriptionA +
'</p><div class="pricing-info__item--price-footer"><div class="pricing-info__item--price">' +
this.renderPrice() +
'</div><div class="pricing-info__item--footer"><p>' +
this.descriptionB +
'</p>' +
pricingTest.svgLogo +
'</div></div></div>' +
this.renderCareIncludedPill() + '</div>'
);
}
// pass each careProfile array as a parameter to the constructor
for (var i = 0; i < careProfiles.length; i++) { Block.apply({}, careProfiles[i]); }
}
};
$(document).ready(function(){ pricingTest.init(); });









share|improve this question









New contributor




jman25 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$








  • 2




    $begingroup$
    Welcome to Code Review! It would be a good idea to explain the source of the data and provide a sample of what that data looks like.
    $endgroup$
    – 200_success
    2 days ago














1












1








1





$begingroup$


The purpose of the pricingTest object is to grab pricing information from the dataLayer on the page and render content blocks accordingly. My goal in posting this is to hopefully receive some feedback in regards to the design pattern used and performance of the code, or anything else you see as worth pointing out. For example:




  1. Is my use of a constructor implemented in a standard and acceptable way?

  2. Is there anything that can be done to optimize the performance of this code?


I've been learning JavaScript for about a year and it is my first language.



// source of the data and details to the best of my understanding
// this is loaded in the <head> of each different page
// each page can have a different combination of 'levelsofcare'
// the 'care_type_id' of 'AL' can have a different 'name' depending on geographic location
// 'AllCareIncluded' is set for individual 'care' levels, excluding 'IL'
// 'Medicaid' and 'SemiPrivateAvailable' are each set at a global level
// 'care_type_category' and 'sort_order' are being ignored for this task
<script type="text/javascript">
var digitalData = {
page: {
pageInfo: {}
}
};
</script>
<script type="text/javascript">
digitalData.page.pageInfo['levelsOfCare'] = [{"care_type_id":"MC","name":"Memory Care","care_type_category":"resident","sort_order":3},{"care_type_id":"AL","name":"Personal Care Home","care_type_category":"resident","sort_order":4},{"care_type_id":"IL","name":"Independent Living","care_type_category":"resident","sort_order":5}];
digitalData.page.pageInfo['pricingIL'] = '2600';
digitalData.page.pageInfo['pricingAL'] = '5817';
digitalData.page.pageInfo['pricingMC'] = '8558';
digitalData.page.pageInfo['pricingAllCareIncludedAL'] = '0';
digitalData.page.pageInfo['pricingAllCareIncludedMC'] = '1';
digitalData.page.pageInfo['pricingMedicaid'] = '0';
digitalData.page.pageInfo['pricingSemiPrivateAvailable'] = '1';
</script>
// end source of the data

var pricingTest = {
careLevels: digitalData.page.pageInfo.levelsOfCare,
ilPrice: digitalData.page.pageInfo.pricingIL,
alPrice: digitalData.page.pageInfo.pricingAL,
mcPrice: digitalData.page.pageInfo.pricingMC,
ilCareIncluded: '0',
alCareIncluded: digitalData.page.pageInfo.pricingAllCareIncludedAL || '0',
mcCareIncluded: digitalData.page.pageInfo.pricingAllCareIncludedMC || '0',
medicaid: digitalData.page.pageInfo.pricingMedicaid,
semiPrivate: digitalData.page.pageInfo.pricingSemiPrivateAvailable,
iconLinkTails: {
MC: 'mc-path-ending',
AL: 'al-path-ending',
IL: 'il-path-ending'
},
descriptions: {
MC: [
'MC Description A',
'MC Description B'
],
AL: [
'AL Description A',
'AL Description B'
],
IL: [
'IL Description A',
'IL Description B'
]
},
svgLogo: '<svg class="pricing-info__item--leaf" height="82px" version="1.1" viewbox="0 0 50 82" width="50px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">...</svg>',
checkLargeAlMcPriceGap: function () {
if (pricingTest.mcPrice - pricingTest.alPrice > 1500) {
console.log("MC Price: " + pricingTest.mcPrice + " AL Price: " + pricingTest.alPrice + " Difference is greater than 1500");
return true;
}
},
checkIfMedicaid: function () {
if (pricingTest.medicaid === '1') {
return '<p class="pricing-info__footer-medicaid"><span class="fa fa-dollar"></span>Medicaid accepted at this community</p>';
} else {
return '';
}
},
checkIfSemiPrivate: function () {
if (pricingTest.semiPrivate === '1') {
return '<p class="pricing-info__footer-semiprivate"><span class="fa fa-arrow-down"></span>Semiprivate rooms available at a lower cost</p>';
} else {
return '';
}
},
init: function () {
// polyfill Array.prototype.map
if(!Array.prototype.map){Array.prototype.map=function(callback){var T,A,k;if(this==null){throw new TypeError("this is null or not defined");}var O=Object(this);var len=O.length>>>0;if(typeof callback!=="function"){throw new TypeError(callback+" is not a function");}if(arguments.length>1){T=arguments[1];}A=new Array(len);k=0;while(k<len){var kValue,mappedValue;if(k in O){kValue=O[k];mappedValue=callback.call(T,kValue,k,O);A[k]=mappedValue;}k++;}return A;};}
// end polyfill
function getYesterdaysDate() {
var today = new Date();
var yesterday = new Date(today);
yesterday.setDate(today.getDate() - 1);
var dd = yesterday.getDate();
var mm = yesterday.getMonth() + 1;
var yyyy = yesterday.getFullYear();
if (dd < 10) { dd = '0' + dd; } if (mm < 10) { mm = '0' + mm; }
yesterday = mm + '/' + dd + '/' + yyyy;
return '<span class="pricing-info__date">As of ' + yesterday + '</span>';
}
var outerAnchor = document.querySelector('.communityTwoColumn');
var communityName = document.querySelector('h1[itemprop="name"]').textContent;
outerAnchor.insertAdjacentHTML("afterEnd", '<div id="pricingInfo"><div class="pricing-info retain retain--padded"><div class="headline3 text-center">Pricing for ' +
communityName +
getYesterdaysDate() +
'</div><div class="flex-row row" id="pricing-info-row"></div><div class="pricing-info__footer text-center"><div class="pricing-info__footer-community-specials">' +
pricingTest.checkIfMedicaid() +
pricingTest.checkIfSemiPrivate() + '</div><p class="pricing-info__footer--heading">For more details on pricing and availability</p><div class="pricing-info__footer--ctas"><div>Call <a class="pricing-info__footer--phone" href="tel:800-350-3800">800-350-3800</a></div><div><span>or</span></div><div><a class="pricing-info__footer--form-link hidden-md hidden-lg" onclick="app.communityCTAContactForm.openMobileScrollandShowLogin(event, this)" href="#">Complete the form above</a><a class="pricing-info__footer--form-link hidden-xs hidden-sm" onclick="functionName(event)" href="#">Complete the form above</a></div></div><p class="pricing-info__footer--disclaimer"><span class="pricing-info__footer--disclaimer-asterisk">*</span>Lorem ipsum dolor sit amet.</p></div></div></div>'
);
function getCareName(item) {
var careProfile = [item.care_type_id, item.name];
if (item.care_type_id === "IL") {
careProfile.push(
pricingTest.iconLinkTails.IL,
pricingTest.descriptions.IL[0],
parseInt(pricingTest.ilPrice, 10).toLocaleString("en"),
pricingTest.ilCareIncluded,
pricingTest.descriptions.IL[1]
);
} else if (item.care_type_id === "AL") {
careProfile.push(
pricingTest.iconLinkTails.AL,
pricingTest.descriptions.AL[0],
parseInt(pricingTest.alPrice, 10).toLocaleString("en"),
pricingTest.alCareIncluded,
pricingTest.descriptions.AL[1]
);
} else if (item.care_type_id === "MC") {
careProfile.push(
pricingTest.iconLinkTails.MC,
pricingTest.descriptions.MC[0],
parseInt(pricingTest.mcPrice, 10).toLocaleString("en"),
pricingTest.mcCareIncluded,
pricingTest.descriptions.MC[1]
);
}
return careProfile;
}
var careProfiles = pricingTest.careLevels.map(getCareName);
var innerAnchor = document.getElementById('pricing-info-row');
// Constructor
function Block(careId, careName, iconLinkTail, descriptionA, price, careIncluded, descriptionB) {
this.careId = careId;
this.careName = careName;
this.iconLinkTail = iconLinkTail;
this.descriptionA = descriptionA;
this.price = price;
this.careIncluded = careIncluded;
this.descriptionB = descriptionB;
this.renderPrice = function () {
if (this.price === "NaN" || (this.careId === "MC" && pricingTest.checkLargeAlMcPriceGap() === true)) {
return 'Call for Pricing';
} else {
return '<p class="pricing-info__item--price-label">– Base Rental Rate –</p><p>Starting at <span id="itemPrice">$' + this.price + '</span><span class="pricing-info__item--price-asterisk">*</span>per month</p>';
}
};
this.renderCareIncludedPill = function () {
if (this.careIncluded === '1') {
return '<div class="pricing-info__item--care-included"><span class="fa fa-heart"></span>Care Included*</div>';
} else {
return '';
}
};
innerAnchor.insertAdjacentHTML(
"beforeEnd",
'<div class="col-md-4 text-center pricing-info__care-included-' +
this.careIncluded +
'" id="pricingBlock' +
this.careId +
'"><div class="pricing-info__item"><img src="https://www.domain.com/content/path/path/en/icons/' +
this.iconLinkTail +
'-icon.svg" alt="' +
this.careName +
' Icon" height="84px" width="84px" /><p class="pricing-info__item--heading">' +
this.careName +
'</p><p class="pricing-info__item--description">' +
this.descriptionA +
'</p><div class="pricing-info__item--price-footer"><div class="pricing-info__item--price">' +
this.renderPrice() +
'</div><div class="pricing-info__item--footer"><p>' +
this.descriptionB +
'</p>' +
pricingTest.svgLogo +
'</div></div></div>' +
this.renderCareIncludedPill() + '</div>'
);
}
// pass each careProfile array as a parameter to the constructor
for (var i = 0; i < careProfiles.length; i++) { Block.apply({}, careProfiles[i]); }
}
};
$(document).ready(function(){ pricingTest.init(); });









share|improve this question









New contributor




jman25 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$




The purpose of the pricingTest object is to grab pricing information from the dataLayer on the page and render content blocks accordingly. My goal in posting this is to hopefully receive some feedback in regards to the design pattern used and performance of the code, or anything else you see as worth pointing out. For example:




  1. Is my use of a constructor implemented in a standard and acceptable way?

  2. Is there anything that can be done to optimize the performance of this code?


I've been learning JavaScript for about a year and it is my first language.



// source of the data and details to the best of my understanding
// this is loaded in the <head> of each different page
// each page can have a different combination of 'levelsofcare'
// the 'care_type_id' of 'AL' can have a different 'name' depending on geographic location
// 'AllCareIncluded' is set for individual 'care' levels, excluding 'IL'
// 'Medicaid' and 'SemiPrivateAvailable' are each set at a global level
// 'care_type_category' and 'sort_order' are being ignored for this task
<script type="text/javascript">
var digitalData = {
page: {
pageInfo: {}
}
};
</script>
<script type="text/javascript">
digitalData.page.pageInfo['levelsOfCare'] = [{"care_type_id":"MC","name":"Memory Care","care_type_category":"resident","sort_order":3},{"care_type_id":"AL","name":"Personal Care Home","care_type_category":"resident","sort_order":4},{"care_type_id":"IL","name":"Independent Living","care_type_category":"resident","sort_order":5}];
digitalData.page.pageInfo['pricingIL'] = '2600';
digitalData.page.pageInfo['pricingAL'] = '5817';
digitalData.page.pageInfo['pricingMC'] = '8558';
digitalData.page.pageInfo['pricingAllCareIncludedAL'] = '0';
digitalData.page.pageInfo['pricingAllCareIncludedMC'] = '1';
digitalData.page.pageInfo['pricingMedicaid'] = '0';
digitalData.page.pageInfo['pricingSemiPrivateAvailable'] = '1';
</script>
// end source of the data

var pricingTest = {
careLevels: digitalData.page.pageInfo.levelsOfCare,
ilPrice: digitalData.page.pageInfo.pricingIL,
alPrice: digitalData.page.pageInfo.pricingAL,
mcPrice: digitalData.page.pageInfo.pricingMC,
ilCareIncluded: '0',
alCareIncluded: digitalData.page.pageInfo.pricingAllCareIncludedAL || '0',
mcCareIncluded: digitalData.page.pageInfo.pricingAllCareIncludedMC || '0',
medicaid: digitalData.page.pageInfo.pricingMedicaid,
semiPrivate: digitalData.page.pageInfo.pricingSemiPrivateAvailable,
iconLinkTails: {
MC: 'mc-path-ending',
AL: 'al-path-ending',
IL: 'il-path-ending'
},
descriptions: {
MC: [
'MC Description A',
'MC Description B'
],
AL: [
'AL Description A',
'AL Description B'
],
IL: [
'IL Description A',
'IL Description B'
]
},
svgLogo: '<svg class="pricing-info__item--leaf" height="82px" version="1.1" viewbox="0 0 50 82" width="50px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">...</svg>',
checkLargeAlMcPriceGap: function () {
if (pricingTest.mcPrice - pricingTest.alPrice > 1500) {
console.log("MC Price: " + pricingTest.mcPrice + " AL Price: " + pricingTest.alPrice + " Difference is greater than 1500");
return true;
}
},
checkIfMedicaid: function () {
if (pricingTest.medicaid === '1') {
return '<p class="pricing-info__footer-medicaid"><span class="fa fa-dollar"></span>Medicaid accepted at this community</p>';
} else {
return '';
}
},
checkIfSemiPrivate: function () {
if (pricingTest.semiPrivate === '1') {
return '<p class="pricing-info__footer-semiprivate"><span class="fa fa-arrow-down"></span>Semiprivate rooms available at a lower cost</p>';
} else {
return '';
}
},
init: function () {
// polyfill Array.prototype.map
if(!Array.prototype.map){Array.prototype.map=function(callback){var T,A,k;if(this==null){throw new TypeError("this is null or not defined");}var O=Object(this);var len=O.length>>>0;if(typeof callback!=="function"){throw new TypeError(callback+" is not a function");}if(arguments.length>1){T=arguments[1];}A=new Array(len);k=0;while(k<len){var kValue,mappedValue;if(k in O){kValue=O[k];mappedValue=callback.call(T,kValue,k,O);A[k]=mappedValue;}k++;}return A;};}
// end polyfill
function getYesterdaysDate() {
var today = new Date();
var yesterday = new Date(today);
yesterday.setDate(today.getDate() - 1);
var dd = yesterday.getDate();
var mm = yesterday.getMonth() + 1;
var yyyy = yesterday.getFullYear();
if (dd < 10) { dd = '0' + dd; } if (mm < 10) { mm = '0' + mm; }
yesterday = mm + '/' + dd + '/' + yyyy;
return '<span class="pricing-info__date">As of ' + yesterday + '</span>';
}
var outerAnchor = document.querySelector('.communityTwoColumn');
var communityName = document.querySelector('h1[itemprop="name"]').textContent;
outerAnchor.insertAdjacentHTML("afterEnd", '<div id="pricingInfo"><div class="pricing-info retain retain--padded"><div class="headline3 text-center">Pricing for ' +
communityName +
getYesterdaysDate() +
'</div><div class="flex-row row" id="pricing-info-row"></div><div class="pricing-info__footer text-center"><div class="pricing-info__footer-community-specials">' +
pricingTest.checkIfMedicaid() +
pricingTest.checkIfSemiPrivate() + '</div><p class="pricing-info__footer--heading">For more details on pricing and availability</p><div class="pricing-info__footer--ctas"><div>Call <a class="pricing-info__footer--phone" href="tel:800-350-3800">800-350-3800</a></div><div><span>or</span></div><div><a class="pricing-info__footer--form-link hidden-md hidden-lg" onclick="app.communityCTAContactForm.openMobileScrollandShowLogin(event, this)" href="#">Complete the form above</a><a class="pricing-info__footer--form-link hidden-xs hidden-sm" onclick="functionName(event)" href="#">Complete the form above</a></div></div><p class="pricing-info__footer--disclaimer"><span class="pricing-info__footer--disclaimer-asterisk">*</span>Lorem ipsum dolor sit amet.</p></div></div></div>'
);
function getCareName(item) {
var careProfile = [item.care_type_id, item.name];
if (item.care_type_id === "IL") {
careProfile.push(
pricingTest.iconLinkTails.IL,
pricingTest.descriptions.IL[0],
parseInt(pricingTest.ilPrice, 10).toLocaleString("en"),
pricingTest.ilCareIncluded,
pricingTest.descriptions.IL[1]
);
} else if (item.care_type_id === "AL") {
careProfile.push(
pricingTest.iconLinkTails.AL,
pricingTest.descriptions.AL[0],
parseInt(pricingTest.alPrice, 10).toLocaleString("en"),
pricingTest.alCareIncluded,
pricingTest.descriptions.AL[1]
);
} else if (item.care_type_id === "MC") {
careProfile.push(
pricingTest.iconLinkTails.MC,
pricingTest.descriptions.MC[0],
parseInt(pricingTest.mcPrice, 10).toLocaleString("en"),
pricingTest.mcCareIncluded,
pricingTest.descriptions.MC[1]
);
}
return careProfile;
}
var careProfiles = pricingTest.careLevels.map(getCareName);
var innerAnchor = document.getElementById('pricing-info-row');
// Constructor
function Block(careId, careName, iconLinkTail, descriptionA, price, careIncluded, descriptionB) {
this.careId = careId;
this.careName = careName;
this.iconLinkTail = iconLinkTail;
this.descriptionA = descriptionA;
this.price = price;
this.careIncluded = careIncluded;
this.descriptionB = descriptionB;
this.renderPrice = function () {
if (this.price === "NaN" || (this.careId === "MC" && pricingTest.checkLargeAlMcPriceGap() === true)) {
return 'Call for Pricing';
} else {
return '<p class="pricing-info__item--price-label">– Base Rental Rate –</p><p>Starting at <span id="itemPrice">$' + this.price + '</span><span class="pricing-info__item--price-asterisk">*</span>per month</p>';
}
};
this.renderCareIncludedPill = function () {
if (this.careIncluded === '1') {
return '<div class="pricing-info__item--care-included"><span class="fa fa-heart"></span>Care Included*</div>';
} else {
return '';
}
};
innerAnchor.insertAdjacentHTML(
"beforeEnd",
'<div class="col-md-4 text-center pricing-info__care-included-' +
this.careIncluded +
'" id="pricingBlock' +
this.careId +
'"><div class="pricing-info__item"><img src="https://www.domain.com/content/path/path/en/icons/' +
this.iconLinkTail +
'-icon.svg" alt="' +
this.careName +
' Icon" height="84px" width="84px" /><p class="pricing-info__item--heading">' +
this.careName +
'</p><p class="pricing-info__item--description">' +
this.descriptionA +
'</p><div class="pricing-info__item--price-footer"><div class="pricing-info__item--price">' +
this.renderPrice() +
'</div><div class="pricing-info__item--footer"><p>' +
this.descriptionB +
'</p>' +
pricingTest.svgLogo +
'</div></div></div>' +
this.renderCareIncludedPill() + '</div>'
);
}
// pass each careProfile array as a parameter to the constructor
for (var i = 0; i < careProfiles.length; i++) { Block.apply({}, careProfiles[i]); }
}
};
$(document).ready(function(){ pricingTest.init(); });






javascript performance beginner jquery






share|improve this question









New contributor




jman25 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




jman25 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited yesterday







jman25













New contributor




jman25 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 2 days ago









jman25jman25

134




134




New contributor




jman25 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





jman25 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






jman25 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








  • 2




    $begingroup$
    Welcome to Code Review! It would be a good idea to explain the source of the data and provide a sample of what that data looks like.
    $endgroup$
    – 200_success
    2 days ago














  • 2




    $begingroup$
    Welcome to Code Review! It would be a good idea to explain the source of the data and provide a sample of what that data looks like.
    $endgroup$
    – 200_success
    2 days ago








2




2




$begingroup$
Welcome to Code Review! It would be a good idea to explain the source of the data and provide a sample of what that data looks like.
$endgroup$
– 200_success
2 days ago




$begingroup$
Welcome to Code Review! It would be a good idea to explain the source of the data and provide a sample of what that data looks like.
$endgroup$
– 200_success
2 days ago










1 Answer
1






active

oldest

votes


















1












$begingroup$

Old school




"I've been learning JavaScript for about a year and it is my first language."




Welcome to the world of programming where learning and the eagerness to learn is a primary skill all good programmers must have stay relevant in the ever changing IT industry.



That segues me to the issue with your code. It is near 9 years out of date, wherever you are getting your study material from it is time to look for something current.



The current draft version is ECMAScript2019 which is what you should be learning. Your code is haphazardly pre ES5 which was released in 2011.



The first line inside the init function (the Array.map polyfill) pre-dates even ES5.



Questions




"Is my use of a constructor implemented in a standard and acceptable way?"




No the standard is ES2018/19




"Is there anything that can be done to optimize the performance of this code?"




Yes, update to ES2018/19



For a reasonably up to date reference MDN Javascript is not as dry as the official ECMA-262 site.



Good points




  • Your code has a consistent style and good layout (indentation, naming format, spaces, etc), however some line lengths are a little too long.


  • Correct use of equality operators, and statement block layout.


  • Good naming, room for improvement but nothing to leave me guessing.



Note I qualified the good points so to avoid CR commenting backlash



Bad points




  • Bad data structuring


eg if you have a set of named items that share the same category/association move the cat name out of the names and create an object to hold the items.



ilPrice: digitalData.page.pageInfo.pricingIL,
alPrice: digitalData.page.pageInfo.pricingAL,
mcPrice: digitalData.page.pageInfo.pricingMC,


should be



price: {
il: digitalData.page.pageInfo.pricingIL,
al: digitalData.page.pageInfo.pricingAL,
mc: digitalData.page.pageInfo.pricingMC,
}




  • Repetitive




    • Repeated long accessors. If you repeatably access values via a long object paths, create a reference to the object needed, don't use the full path each time. See Ex A

    • Repeated code. There are is a section where you have the same 7 lines repeated 3 times with the only difference between 3 is 2 characters.




Ex A (As your code needs a rewrite from the ground up, the example does the above using a IIFE and default parameter as example only)



price: {
il: digitalData.page.pageInfo.pricingIL,
al: digitalData.page.pageInfo.pricingAL,
mc: digitalData.page.pageInfo.pricingMC,
},


price: ((info = digitalData.page.pageInfo) => ({
il: info.pricingIL,
al: info.pricingAL,
mc: info.pricingMC,
}))(),



  • Magic constants. There are many repeated constants as strings, parts of strings, numbers, distributed throughout your code. Move these out of the code and define them as named constants in one place. You should not have to navigate the body of the code to change a simple number, or string.


  • Don't add HTML to the page via strings, use the DOM API to create and modify elements, its significantly quicker, and lets you structure your code to better fit its role.



Summary



All in all not bad for one year, I have seen worse code from CS post-grads with 5 years under their belts.



Just don't fall behind. If you are worried about legacy browser support use a transpiler like Babel.js, don't let a tiny, tiny tiny minority hold your skill development back.






share|improve this answer









$endgroup$













  • $begingroup$
    Thank you for your feedback Blindman67! I'll take these notes and improve my my code and approach.
    $endgroup$
    – jman25
    yesterday












Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});






jman25 is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216989%2floop-through-data-layer-and-display-dynamic-content%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1












$begingroup$

Old school




"I've been learning JavaScript for about a year and it is my first language."




Welcome to the world of programming where learning and the eagerness to learn is a primary skill all good programmers must have stay relevant in the ever changing IT industry.



That segues me to the issue with your code. It is near 9 years out of date, wherever you are getting your study material from it is time to look for something current.



The current draft version is ECMAScript2019 which is what you should be learning. Your code is haphazardly pre ES5 which was released in 2011.



The first line inside the init function (the Array.map polyfill) pre-dates even ES5.



Questions




"Is my use of a constructor implemented in a standard and acceptable way?"




No the standard is ES2018/19




"Is there anything that can be done to optimize the performance of this code?"




Yes, update to ES2018/19



For a reasonably up to date reference MDN Javascript is not as dry as the official ECMA-262 site.



Good points




  • Your code has a consistent style and good layout (indentation, naming format, spaces, etc), however some line lengths are a little too long.


  • Correct use of equality operators, and statement block layout.


  • Good naming, room for improvement but nothing to leave me guessing.



Note I qualified the good points so to avoid CR commenting backlash



Bad points




  • Bad data structuring


eg if you have a set of named items that share the same category/association move the cat name out of the names and create an object to hold the items.



ilPrice: digitalData.page.pageInfo.pricingIL,
alPrice: digitalData.page.pageInfo.pricingAL,
mcPrice: digitalData.page.pageInfo.pricingMC,


should be



price: {
il: digitalData.page.pageInfo.pricingIL,
al: digitalData.page.pageInfo.pricingAL,
mc: digitalData.page.pageInfo.pricingMC,
}




  • Repetitive




    • Repeated long accessors. If you repeatably access values via a long object paths, create a reference to the object needed, don't use the full path each time. See Ex A

    • Repeated code. There are is a section where you have the same 7 lines repeated 3 times with the only difference between 3 is 2 characters.




Ex A (As your code needs a rewrite from the ground up, the example does the above using a IIFE and default parameter as example only)



price: {
il: digitalData.page.pageInfo.pricingIL,
al: digitalData.page.pageInfo.pricingAL,
mc: digitalData.page.pageInfo.pricingMC,
},


price: ((info = digitalData.page.pageInfo) => ({
il: info.pricingIL,
al: info.pricingAL,
mc: info.pricingMC,
}))(),



  • Magic constants. There are many repeated constants as strings, parts of strings, numbers, distributed throughout your code. Move these out of the code and define them as named constants in one place. You should not have to navigate the body of the code to change a simple number, or string.


  • Don't add HTML to the page via strings, use the DOM API to create and modify elements, its significantly quicker, and lets you structure your code to better fit its role.



Summary



All in all not bad for one year, I have seen worse code from CS post-grads with 5 years under their belts.



Just don't fall behind. If you are worried about legacy browser support use a transpiler like Babel.js, don't let a tiny, tiny tiny minority hold your skill development back.






share|improve this answer









$endgroup$













  • $begingroup$
    Thank you for your feedback Blindman67! I'll take these notes and improve my my code and approach.
    $endgroup$
    – jman25
    yesterday
















1












$begingroup$

Old school




"I've been learning JavaScript for about a year and it is my first language."




Welcome to the world of programming where learning and the eagerness to learn is a primary skill all good programmers must have stay relevant in the ever changing IT industry.



That segues me to the issue with your code. It is near 9 years out of date, wherever you are getting your study material from it is time to look for something current.



The current draft version is ECMAScript2019 which is what you should be learning. Your code is haphazardly pre ES5 which was released in 2011.



The first line inside the init function (the Array.map polyfill) pre-dates even ES5.



Questions




"Is my use of a constructor implemented in a standard and acceptable way?"




No the standard is ES2018/19




"Is there anything that can be done to optimize the performance of this code?"




Yes, update to ES2018/19



For a reasonably up to date reference MDN Javascript is not as dry as the official ECMA-262 site.



Good points




  • Your code has a consistent style and good layout (indentation, naming format, spaces, etc), however some line lengths are a little too long.


  • Correct use of equality operators, and statement block layout.


  • Good naming, room for improvement but nothing to leave me guessing.



Note I qualified the good points so to avoid CR commenting backlash



Bad points




  • Bad data structuring


eg if you have a set of named items that share the same category/association move the cat name out of the names and create an object to hold the items.



ilPrice: digitalData.page.pageInfo.pricingIL,
alPrice: digitalData.page.pageInfo.pricingAL,
mcPrice: digitalData.page.pageInfo.pricingMC,


should be



price: {
il: digitalData.page.pageInfo.pricingIL,
al: digitalData.page.pageInfo.pricingAL,
mc: digitalData.page.pageInfo.pricingMC,
}




  • Repetitive




    • Repeated long accessors. If you repeatably access values via a long object paths, create a reference to the object needed, don't use the full path each time. See Ex A

    • Repeated code. There are is a section where you have the same 7 lines repeated 3 times with the only difference between 3 is 2 characters.




Ex A (As your code needs a rewrite from the ground up, the example does the above using a IIFE and default parameter as example only)



price: {
il: digitalData.page.pageInfo.pricingIL,
al: digitalData.page.pageInfo.pricingAL,
mc: digitalData.page.pageInfo.pricingMC,
},


price: ((info = digitalData.page.pageInfo) => ({
il: info.pricingIL,
al: info.pricingAL,
mc: info.pricingMC,
}))(),



  • Magic constants. There are many repeated constants as strings, parts of strings, numbers, distributed throughout your code. Move these out of the code and define them as named constants in one place. You should not have to navigate the body of the code to change a simple number, or string.


  • Don't add HTML to the page via strings, use the DOM API to create and modify elements, its significantly quicker, and lets you structure your code to better fit its role.



Summary



All in all not bad for one year, I have seen worse code from CS post-grads with 5 years under their belts.



Just don't fall behind. If you are worried about legacy browser support use a transpiler like Babel.js, don't let a tiny, tiny tiny minority hold your skill development back.






share|improve this answer









$endgroup$













  • $begingroup$
    Thank you for your feedback Blindman67! I'll take these notes and improve my my code and approach.
    $endgroup$
    – jman25
    yesterday














1












1








1





$begingroup$

Old school




"I've been learning JavaScript for about a year and it is my first language."




Welcome to the world of programming where learning and the eagerness to learn is a primary skill all good programmers must have stay relevant in the ever changing IT industry.



That segues me to the issue with your code. It is near 9 years out of date, wherever you are getting your study material from it is time to look for something current.



The current draft version is ECMAScript2019 which is what you should be learning. Your code is haphazardly pre ES5 which was released in 2011.



The first line inside the init function (the Array.map polyfill) pre-dates even ES5.



Questions




"Is my use of a constructor implemented in a standard and acceptable way?"




No the standard is ES2018/19




"Is there anything that can be done to optimize the performance of this code?"




Yes, update to ES2018/19



For a reasonably up to date reference MDN Javascript is not as dry as the official ECMA-262 site.



Good points




  • Your code has a consistent style and good layout (indentation, naming format, spaces, etc), however some line lengths are a little too long.


  • Correct use of equality operators, and statement block layout.


  • Good naming, room for improvement but nothing to leave me guessing.



Note I qualified the good points so to avoid CR commenting backlash



Bad points




  • Bad data structuring


eg if you have a set of named items that share the same category/association move the cat name out of the names and create an object to hold the items.



ilPrice: digitalData.page.pageInfo.pricingIL,
alPrice: digitalData.page.pageInfo.pricingAL,
mcPrice: digitalData.page.pageInfo.pricingMC,


should be



price: {
il: digitalData.page.pageInfo.pricingIL,
al: digitalData.page.pageInfo.pricingAL,
mc: digitalData.page.pageInfo.pricingMC,
}




  • Repetitive




    • Repeated long accessors. If you repeatably access values via a long object paths, create a reference to the object needed, don't use the full path each time. See Ex A

    • Repeated code. There are is a section where you have the same 7 lines repeated 3 times with the only difference between 3 is 2 characters.




Ex A (As your code needs a rewrite from the ground up, the example does the above using a IIFE and default parameter as example only)



price: {
il: digitalData.page.pageInfo.pricingIL,
al: digitalData.page.pageInfo.pricingAL,
mc: digitalData.page.pageInfo.pricingMC,
},


price: ((info = digitalData.page.pageInfo) => ({
il: info.pricingIL,
al: info.pricingAL,
mc: info.pricingMC,
}))(),



  • Magic constants. There are many repeated constants as strings, parts of strings, numbers, distributed throughout your code. Move these out of the code and define them as named constants in one place. You should not have to navigate the body of the code to change a simple number, or string.


  • Don't add HTML to the page via strings, use the DOM API to create and modify elements, its significantly quicker, and lets you structure your code to better fit its role.



Summary



All in all not bad for one year, I have seen worse code from CS post-grads with 5 years under their belts.



Just don't fall behind. If you are worried about legacy browser support use a transpiler like Babel.js, don't let a tiny, tiny tiny minority hold your skill development back.






share|improve this answer









$endgroup$



Old school




"I've been learning JavaScript for about a year and it is my first language."




Welcome to the world of programming where learning and the eagerness to learn is a primary skill all good programmers must have stay relevant in the ever changing IT industry.



That segues me to the issue with your code. It is near 9 years out of date, wherever you are getting your study material from it is time to look for something current.



The current draft version is ECMAScript2019 which is what you should be learning. Your code is haphazardly pre ES5 which was released in 2011.



The first line inside the init function (the Array.map polyfill) pre-dates even ES5.



Questions




"Is my use of a constructor implemented in a standard and acceptable way?"




No the standard is ES2018/19




"Is there anything that can be done to optimize the performance of this code?"




Yes, update to ES2018/19



For a reasonably up to date reference MDN Javascript is not as dry as the official ECMA-262 site.



Good points




  • Your code has a consistent style and good layout (indentation, naming format, spaces, etc), however some line lengths are a little too long.


  • Correct use of equality operators, and statement block layout.


  • Good naming, room for improvement but nothing to leave me guessing.



Note I qualified the good points so to avoid CR commenting backlash



Bad points




  • Bad data structuring


eg if you have a set of named items that share the same category/association move the cat name out of the names and create an object to hold the items.



ilPrice: digitalData.page.pageInfo.pricingIL,
alPrice: digitalData.page.pageInfo.pricingAL,
mcPrice: digitalData.page.pageInfo.pricingMC,


should be



price: {
il: digitalData.page.pageInfo.pricingIL,
al: digitalData.page.pageInfo.pricingAL,
mc: digitalData.page.pageInfo.pricingMC,
}




  • Repetitive




    • Repeated long accessors. If you repeatably access values via a long object paths, create a reference to the object needed, don't use the full path each time. See Ex A

    • Repeated code. There are is a section where you have the same 7 lines repeated 3 times with the only difference between 3 is 2 characters.




Ex A (As your code needs a rewrite from the ground up, the example does the above using a IIFE and default parameter as example only)



price: {
il: digitalData.page.pageInfo.pricingIL,
al: digitalData.page.pageInfo.pricingAL,
mc: digitalData.page.pageInfo.pricingMC,
},


price: ((info = digitalData.page.pageInfo) => ({
il: info.pricingIL,
al: info.pricingAL,
mc: info.pricingMC,
}))(),



  • Magic constants. There are many repeated constants as strings, parts of strings, numbers, distributed throughout your code. Move these out of the code and define them as named constants in one place. You should not have to navigate the body of the code to change a simple number, or string.


  • Don't add HTML to the page via strings, use the DOM API to create and modify elements, its significantly quicker, and lets you structure your code to better fit its role.



Summary



All in all not bad for one year, I have seen worse code from CS post-grads with 5 years under their belts.



Just don't fall behind. If you are worried about legacy browser support use a transpiler like Babel.js, don't let a tiny, tiny tiny minority hold your skill development back.







share|improve this answer












share|improve this answer



share|improve this answer










answered 2 days ago









Blindman67Blindman67

9,2351621




9,2351621












  • $begingroup$
    Thank you for your feedback Blindman67! I'll take these notes and improve my my code and approach.
    $endgroup$
    – jman25
    yesterday


















  • $begingroup$
    Thank you for your feedback Blindman67! I'll take these notes and improve my my code and approach.
    $endgroup$
    – jman25
    yesterday
















$begingroup$
Thank you for your feedback Blindman67! I'll take these notes and improve my my code and approach.
$endgroup$
– jman25
yesterday




$begingroup$
Thank you for your feedback Blindman67! I'll take these notes and improve my my code and approach.
$endgroup$
– jman25
yesterday










jman25 is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















jman25 is a new contributor. Be nice, and check out our Code of Conduct.













jman25 is a new contributor. Be nice, and check out our Code of Conduct.












jman25 is a new contributor. Be nice, and check out our Code of Conduct.
















Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f216989%2floop-through-data-layer-and-display-dynamic-content%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

is 'sed' thread safeWhat should someone know about using Python scripts in the shell?Nexenta bash script uses...

How do i solve the “ No module named 'mlxtend' ” issue on Jupyter?

Pilgersdorf Inhaltsverzeichnis Geografie | Geschichte | Bevölkerungsentwicklung | Politik | Kultur...