Custom Datatypes in JS - javascript

I'm tying to model a custom data type with JS and wondering if there's a more elegant way of doing this.
Ultimately I'd like the data type to essentially behave like an array but with an extended set of methods to meet my specific application and can be seen in the Links class below.
class Node {
constructor() {
this.links = new Links();
}
}
class Links {
constructor(node) {
this.data = [];
}
initialize() {
let initArray = [];
let maximumIncrement = hypotheticalNodeArray.length;
for (let i = 0; i < maximumIncrement ; i++) {
array[i] = 0;
}
this.data = array;
}
// More Methods Here
}
Essentially my issue is if I were to attempt to access the links data with [ node.links ] the entire object would be returned where as I'd love it just to return the data property as if the data had been accessed with [ node.links.data ].
I'm aware that just having to add that extra property isn't the end of the world, but I'd really like it if the object were to behave like an array except with an extended set of methods.
I'm not sure if this possible and I appreciate it's rather pedantic, however it would really clean the code I'm working on up.

You could define a getter that returns the internal array:
class Node {
constructor() {
// renamed “_links” because we want the getter named “links”
this._links = new Links();
}
get links () {
return this._links.data;
}
}
const node = new Node();
node.links.map( ... ) // node.links is node._links.data

Related

adding multiple properties to object in a loop

I think my question is easy but I dont understand why my solution doesnt work :(
I'm trying to add to a new object some long properties using foreach loop but I'm getting the whole time error.
Could someone please help me?
let i = 0;
const obj = {};
for (const item of read) {
console.log(item.name);
console.log(item.imageURL);
obj['hits']['hits'] ='whyDosntWork';
console.log(item.name);
if (item.imageURL) {
obj['hits']['hits'][i]['_source.ActiveChannelReleases'][0]['ImageExports'][0]['Resolutions'][0]['Url'] =getServerURL()+item.imageURL;
} else {
obj['hits']['hits'][i]['_source.ActiveChannelReleases'][0]['ImageExports'][0]['Resolutions'][0]['Url'] ='https://cdn3.iconfinder.com/data/icons/kitchen-glyph-black/2048/4834_-_Cookbook-512.png';
}
console.log(item.imageURL);
i++;
}
I have an response and I want to mock it with my data
I wish to have for example an object that I can fill with data:
class ResponseController {
constructor() {
this.response = {
'hits': {
'hits': [{'_source.ActiveChannelReleases': [{'ImageExports': ['Resolutions']}],
}],
},
};
}
}
module.exports = ResponseController;
Will it work if I write
obj = new ResponseController();
and then I can easily add variables from the looo?
First this is a madness :).
Why is not working?
const obj = {};
you cannot do this obj['hits']['hits'] ='whyDosntWork'; due to obj['hist'] does not exists.
You need to do:
obj['hits'] = {}
and then obj['hits']['hits'] ='whyDosntWork';
And the same for the rest...
I cannot understand what do you want to do here:
obj['hits']['hits'][i]['_source.ActiveChannelReleases'][0]['ImageExports'][0]['Resolutions'][0]['Url']
But follow what I said before, you need to create each step the value you want. I can assume that you want an array in ´hits`...
The issue is that you're defining obj to be an object, and then are trying to add stuff into obj.hits without defining that as an object
const obj = {};
obj['hits'] = {}
obj['hits']['hits'] ='whyDosntWork';

Container Class in Javascript

Total OOP beginner and doing all this in Javascript, so forgive any blatant dumbness on my part:
I want to keep track of dynamically created objects. I believe my solution to this problem is to use a container class.
Is a container class what I want?
If yes, is my implementation correct?
Branch objects are dynamically generated.
Branches objects contain a Branch objects array.
function Branches() {
function Branch() {
var _id;
_id = Math.round(Math.random()*10);
this.getId = function() {
return _id;
}
}
this.createBranch = function() {
var branch = new Branch;
_branches.push(branch);
}
this.getBranches = function() {
return _branches;
}
this.getBranchIds = function() {
var branch_list = this.getBranches();
var branch_ids = [];
for (var i = 0; i < branch_list.length; i++) {
var branch_id = branch_list[i].getId();
branch_ids.push(branch_id);
}
return branch_ids;
}
var _branches = [];
}
// code test
var test = new Branches;
for (var i = 0; i < 7; i++) {
test.createBranch();
}
console.log("Branch IDs:\n" + test.getBranchIds());
Your code works (yay!) despite a few simple problems (you're not generating unique IDs for each branch, for example). If you are happy with the design you chose, feel free to take the code to Code Review. There you will get tips for improving the code as it currently is.
To answer your first, more conceptual question, what you've written is definitely one way to implement what you want. You've gone with a Factory pattern here. You've written a class, Branches, that provides an interface for creating objects of the class Branch.
createBranch is known as a Factory method; it handles the creation of the new object, and in your case, keeping track of that object in your array. It also returns the new object so the user can interact with the Branch object as necessary.
One thing to consider about your implementation is that Branch is private, visible only to code inside the Branches class. This has a few implications that come to mind:
the only way to create a Branch object is through the createBranch factory
all Branch objects will be tracked because of this
Any properties of the Branch constructor (meaning, anything like Branch.property = value) will not be immediately accessible outside of the Branches class.
This may be what you want. But if there is no reason to hide the Branch constructor or prototype from plain sight, then I'd suggest other design patterns.
A good strategy might be to use those constructor properties. This way, you reduce your code by a lot, and have one fewer class to deal with (but no factory methods):
function Branch() {
var _id = Math.round(Math.random() * 10);
this.getId = function () {
return _id;
};
Branch.branches.push(this);
}
Branch.branches = [];
Branch.getIds = function () {
var ids = [];
for (var i in Branch.branches)
ids.push(Branch.branches[i].getId());
return ids;
};
// test code
for (var i = 0; i < 7; i++) {
new Branch();
}
console.log("Branch IDs:\n" + Branch.getIds());

javascript - how to get object from array, and use its methods?

i have a problem using a class methods, after it was inserted into array. when i pull it back i can no longer use it methods.
and i know javascript does not have class, when i say class i mean object -or js equal.
suppose i have the following:
// a simple atomic class
function raw_msg(msg) {
this.msg = msg;
this.print = function () {
console.log(this.msg);
}
}
// and then i have this container for this "atomic" class
// which accept array of unknown object (known to me though..) = in_buffer
// i.e in_buffer is just an array of objects (one type of object)
function buffer(in_buffer) {
this.trans_buffer = null;
if (in_buffer!=null)
this.set_buffer (in_buffer);
this.set_buffer = function (buffer) {
this.trans_buffer = [];
var length = buffer.length,
row, new_raw_msg;
for(var x = 0; x < length; x++) {
row = buffer[x];
this.trans_buffer.push(new raw_msg(row));
}
console.log(this.trans_buffer);
}
this.use_some_raw_msg_method = function () {
var firstrow = this.trans_buffer[0];
firstrow.print(); // here is the problem!!!
//this here where i need help as it yield the error:
//Uncaught TypeError: Object #<Object> has no method 'print'
}
}
// this is how i use it, this code sits in a diffrent yet another class...
// this here im just building fake array
var buffer_in = [];
for (var x=0;x<10;x++)
buffer_in.push ("whatever" + x);
this.trans_buffer = new trans_helper(buffer_in);
this.trans_buffer.use_some_raw_msg_method (); // will yield the error as described
i hope this here, is clear, ask away if you need clarifications.
thanks for your help!
note to future readers - there is no problem in retrieving an object and using its methods.
You had several problems with your code.
Associative array does not have .push() method so the following line failed:
buffer_in.push ("whatever" + x);
To fix this just declare plain array:
var buffer_in = [];
You tried to create instance of function called trans_helper which does not exist. The name is buffer instead, so fix would be:
var trans_buffer = new buffer(buffer_in);
Last but not least, you tried to call function in the "class" when it still did not exist yet. JavaScript does not "compile" functions in advance, when inside function it will go line by line. So in this line in your code:
this.set_buffer (in_buffer);
There was still no function called "set_buffer" in your class. To fix this, place the function declaration above, on top.
Live test case.

javascript automatically add property when extending object

When working with JavaScript I've come across a situation where I'm not sure if what I'm trying to accomplish is possible:
Considering the following object:
var data = {};
Is it possible to modify "data" in a way that when extending it in the following way
data.entry_1 = {
'prop_1': 'set_1',
'prop_2': 'set_2'
};
a new property gets automatically attached to the new object, that is to say
data.entry_1 = {
'prop_1': 'set_1',
'prop_2': 'set_2',
id: 1 // automatically created property
};
Is it possible to accomplish the above without having to use "external" methods, e.g. no data.newEntry(object)?
var data = {
set entry_1 (val) {
for(var i in val) { this[i] = val[i] };
this["id"] = 1;
}
}
Supported in IE9+ and all other modern browsers.

Access object in array which is a property of another object - Javascript

It's been a long time since I learned OOP and I'm new to JS, so things might look weird for more advanced users - sorry :)
function page(title) {
this.subPages = [];
this.title = title;
}
page.prototype.addToSubPages = function(subPage) {
this.subPages.push(subPage);
}
page.prototype.getSubPages = function() {
return this.subPages;
}
Now I create 2 objects:
startPage = new page("start");
somePage = new page("foo");
...and try to add somePage into the array in startPage:
startPage.addToSubPages(somePage);
Now this doesn't seem to work, although it should be correct, if I'm not mistaken.
console.log(startPage.getSubPages());
This shows me that something is in the array, but the object appears to be empty. What am I doing wrong?
Also: How would I access a certain element in that array? Like this: startPage.getSubPages()[0].getFoo();?
Edit: Holy Mackerel, Batman! This is more like my actual code: http://jsfiddle.net/pZHKS/2/
You're all right, the code I posted actually works. As soon as inheritance comes into play, it doesn't work anymore. Why, though? It should work exactly like the code above, right?
function page(title) {
this.title = title;
}
function subPage() {
this.contentPages = [];
}
subPage.prototype = new page;
There are two problems.
your not calling page in subPage.
your using Child.prototype = new Parent; that's wrong, use Object.create instead
So the fixed code would be.
function page(title) {
this.title = title;
}
function subPage(title) {
page.call(this, title);
this.contentPages = [];
}
subPage.prototype = Object.create(page.prototype);

Categories