I came across some JavaScript syntax I haven't seen before. Can someone help point me in the right direction, I'm not even sure what I could google to learn more :/
$.variable = function() {
return a(b, [{
key: "setPeriod",
value: function(t) {
this.variable.period = t;
}
}, {
key: "location",
get: function() {
return "earth";
}
}])
}
$.variable.setPeriod("test");
$.variable.location;
My question is what is this structure where an object is defined via a list. Also not sure what the difference between value and get is. Any help would be appreciated.
Here's an example of a snippet:
https://pastebin.com/zymW2XZw
Here my guess about what happens to this list of objects :
var o = s([{
key: "attribute",
value: "default"
}, {
key: "getAttribute",
value: function () {
return this.attribute;
}
}, {
key: "setAttribute",
value: function (value) {
this.attribute = value;
}
}]);
console.log(o.getAttribute());
o.setAttribute("custom");
console.log(o.getAttribute());
function s (members) {
var o = {};
members.forEach(function (member) {
o[member.key] = member.value;
});
return o;
}
I guess the framework needs to preprocess the object's members for some obscure reasons related to the framework internal mecanism.
Related
Task: I want to create a dynamic class by a given JSON Object in ES6.
After a lot of reading in the MDN web docs and much stackoverflow questions i'm totally confused how to get this work.
JSON Object
{
constructor: {
name: "someName",
},
getter: {
function1: () => "someOutput",
function2: () => false,
}
}
While I tried to solve the problem I figured out how to create dynamic getter methods by using "Proxy" or "defineProperty" but how i should handle the constructor?? :(
I hope someone can help me with a hint or an example.
Thanks in advance
You can add constructor to your class created by Proxy using Proxy's "construct" handler method:
const jsonObj = {
constructor: {
name: "someName",
},
getter: {
function1: () => "someOutput",
function2: () => false,
}
}
function baseClass(obj) {
for(i in obj){
this[i] = obj[i]
}
}
const handler = {
construct(target, args) {
return new target(jsonObj.constructor);
}
};
const NewClass = new Proxy(baseClass, handler);
I have created a new web app that has 10 pages / forms and during the load of those pages 6 of the pages / forms call the same JavaScript methods and 4 call the same plus some additional methods. I can obviously call the the methods individually in the page but I'm wondering how I can do this in a more intelligent manner.
Currently all I'm doing is calling the methods at the bottom of the page like:
<script>
somemethod1(someparam1);
somemethod2(someparam1, someparam2);
somemethod3();
somemethod4();
somemethod5(someparam1);
</script>
It would be nicer to call something like:
<script>
Execute('somemethod1', 'somemethod2''somemethod3', 'somemethod4', 'somemethod5')();
</script>
I don't think its a good practice to do it. But sure, it'd be nicer to have Execute function like that if you don't need to pass any parameters.
You can do it like,
function test1() {
console.log('test1');
}
function test2() {
console.log('test2');
}
var Execute = function() {
for (var i = 0; i < arguments.length; i++) {
var funcName = arguments[i];
if (typeof window[funcName] == 'function') {
window[funcName]();
}
}
}
Execute('test1', 'test2')
However, as your question edited that you need to pass specific parameter/s to one or more of the functions, here's the intelligent way to do it.
test1(param1);
test2(param2, param1);
If you have uniform procedures and you need to call them in a certain order, like my example below for iteration nested arrays, then you could use the given proposal, which uses the following functions for the function before.
This might not work for other needs.
function Callback(array) {
this.array = array;
}
Object.defineProperties(Callback.prototype, {
start: {
get: function () {
return this.getCallback(0);
}
},
getCallback: {
value: function (i) {
var that = this;
return this.array[i].bind({ get next() { return that.getCallback(i + 1); } });
}
}
});
// example
function getSubmodel(model, submodel) {
var callback = new Callback([
function (a) { a.Categories.forEach(this.next); },
function (a) { a.forEach(this.next); },
function (a) { if (a.brandname === model) { a.models.forEach(this.next); } },
function (a) { if (a.name === submodel) { a.submodel.forEach(this.next); } },
function (a) { result.push(a.name); }
]),
result = [];
data.forEach(callback.start);
return result;
}
var data = [{
Storename: "Zig Zag Mobiles",
Shopid: "asdef1234",
Categories: [[{
models: [{
submodel: [{
price: null,
name: "Lumia 735 TS"
}, {
price: "3200",
name: "Lumia 510"
}], name: "Lumia"
}],
brandname: "Nokia",
}]]
}];
console.log(getSubmodel('Nokia', 'Lumia'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
it would be nicer to call something like Execute('somemethod1',
'somemethod2''somemethod3', 'somemethod4', 'somemethod5')();
Provided that you do not need to pass in argument(s) to the individual method you can do this:
[func1, func2, func3].map(function(func){
func();
});
Otherwise the way to do it is to just call the methods with the required arguments as you are already doing now unless there is really significant benefits to be gained from creating an abstraction where you can pass in both the method to be called and its associated arguments.
I have checked other questions similar to my problem. but this problem can apparently be different in every case.
Angular Jasmine Test complains
TypeError: 'undefined' is not an object (evaluating 'fields.forEach')at discoverDependentFields
Here is my discoverDependentFields function
discoverDependentFields($scope.response.Fields);
function discoverDependentFields(fields) {
fields.forEach(function (field) {
field.DependencyFieldEvaluated = '';
if (field.DependencyField) {
var foundFields = fields.filter(function (fieldToFind) { return fieldToFind.Name === field.DependencyField; });
if (foundFields.length === 1) {
field.DependencyFieldEvaluated = foundFields[0];
}
}
});
}
and in the test I have this bit
this.controller('MyController', {
'$scope': this.scope,
}
});
this.scope.response.Fields = [
{
Name: "UserIdentity",
Value: {
"FirstName": "John"
},
PropertyName: "User.Identity"
}
];
I use the value of field.DependencyFieldEvaluated in a function in a directive like this
function dependencyMet(field) {
var dependentField = field.DependencyFieldEvaluated;
var met = compareToDependencyValue(field, dependentField.Value);
return met;
}
I have no idea why it is complaining
If
discoverDependentFields($scope.response.Fields);
is a line in your controller, then you need to setup the $scope.response.Fields data before instantiating the controller. In other words, swap the order of operations in your test to be
this.scope = {};
// or maybe this.scope = $rootScope.$new()
this.scope.response = {
Fields: [{
Name: "UserIdentity",
Value: {
FirstName: "John"
},
PropertyName: "User.Identity"
}]
};
this.controller('MyController', {
$scope: this.scope,
});
Given a product might have several attributes such as name, price, sku, description and so on - the following will become quite long winded to describe a product model...
function Product(data) {
var productData = data || {};
Object.defineProperty(this, "sku", {
get: function() {
return productData.sku;
}
});
Object.defineProperty(this, "name", {
get: function() {
return productData.name;
}
});
Object.defineProperty(this, "price", {
get: function() {
return productData.price;
}
});
}
module.exports = Product;
What alternatives are there in javascript for this and how is this normally handled?
#Pointy deserves the points here with Object.defineProperties-
function Product(data) {
var productData = data || {};
Object.defineProperties(this, {
"sku": {
get: function() {
return productData.sku;
}
},
"name": {
get: function() {
return productData.name;
}
},
"price": {
get: function() {
return productData.price;
}
}
});
}
module.exports = Product;
Support is near identical to Object.defineProperty so there is no real reason not to use this method when defining multiple properties at the same time.
You can use a single loop to define all the properties:
var self = this;
Object.keys(productData).forEach(function(prop){
Object.defineProperty(self, prop, {
get: function() {
return productData[prop];
}
});
});
Demo
i have a function that loop all object properties and return value if it qualify certain condition
basically this is how i m doing
//an enum
var BillingType = Object.freeze({
PayMonthly: { key: 'Monthly', value: 1 },
PayYearly: { key: 'Yearly', value: 2 }
});
now to make it work i do this
for (var property in BillingType ) {
if (BillingType .hasOwnProperty(property)) {
if (value === BillingType [property].value) {
return BillingType [property].key;
}
}
}
it works fine but to make it generic for all enums i changed code to
getValue = function (value, object) {
for (var property in object) {
if (object.hasOwnProperty(property)) {
if (value === object[property].value) {
return object[property].key;
}
}
}
}
now when i try to call from other functions
enumService.getValue(1, 'BillingModel');
rather to loop all properties it start loop on its characters.
how can i convert string to object or m doing it totally wrong . any help will be appreciated
Regards
Your getValue looks fine, just call it using
enumService.getValue(1, BillingModel); // <-- no quotes
and here is a working fiddle: http://jsfiddle.net/LVc6G/
and here is the code of the fiddle:
var BillingType = Object.freeze({
PayMonthly: { key: 'Monthly', value: 1 },
PayYearly: { key: 'Yearly', value: 2 }
});
var getValue = function (value, object) {
for (var property in object) {
if (object.hasOwnProperty(property)) {
if (value === object[property].value) {
return object[property].key;
}
}
}
};
alert(getValue(1, BillingType));