create objects using factory in Javascript - javascript

I'm having trying to create two objects of type person using factory and on the first try I create the first element and the second attempt instead of creating the second element creates a new element but with the same characteristics as the first element
class Person
function Person(id, name) {
this.id = id;
this.name = name;
}
class Student extends Person
function Student(id, name) {
Person.call(this, id, name);
}
class Teacher extends Person
function Teacher(id, name) {
Person.call(this, id, name);
}
using function factory to create student and teacher
function Factory() {
this.createPerson = function(type, name) {
var person;
var idStudent = 0;
var idTeacher = 0;
switch (type) {
case "1":
person = new Student(idStudent++, name);
break;
case "2":
person = new Teacher(idTeacher++, name);
break;
}
return person;
}
}
class School has an array of person
function School(id) {
this.persons = [];
this.factory = new Factory();
this.personCreate = null;
this.createStudentAndTeacher = function() {
var type = prompt("Choose ? \n\n[1-Student | 2-Teacher ]");
var name = prompt("Write name?");
if (type !== null) {
this.personCreate = this.factory.createPerson(type,name);
this.persons.push(this.personCreate);
} else {
alert("need to choose");
}
}
}
created by default
var s = new School(1);
var btn = document.createElement('button');
btn.value = "create";
btn.onclick = function(){
s.createStudentAndTeacher();
}
my doubt is when I create the Student object with name "John", return student.id = 0 and student.name = John but when I create the new Student object with name "Elisa", return the same information student.id = 0 and student.name = John and in fact, should return student.id = 1 and student.name = Elisa and if I create new Teacher object with name "Jerry", return the same information student.id = 0 and student.name = John and in fact, should return teacher.id = 0 and teacher.name = Jerry
what I´m doing wrong?

The code has a bug. In the Factory definition, change this
function Factory() {
this.createPerson = function(type, name) {
var person;
var idStudent = 0;
var idTeacher = 0;
to this
function Factory() {
var idStudent = 0;
var idTeacher = 0;
this.createPerson = function(type, name) {
var person;
then use the console, run these lines.
var s = new School();
s.createStudentAndTeacher(); // john
s.createStudentAndTeacher(); // bob
s.persons[0] // id 0:john
s.persons[1] // id 1:bob

Your createPerson is redeclaring idStudent and idTeacher (and resetting them to 0). Try moving that code out of that block.

Related

Trying to return just the description in an array of instances of a class

So this is what I am trying to solve:
class ViewRole {
name
description
constructor(name, description) {
this.name = name;
this.description = description;
}
}
class NewRole {
name;
description;
constructor(name, description) {
this.name = name;
this.description = description;
}
}
var armadilloRoles = [
new NewRole('Billing', 'armadillo.organization.billing'),
new NewRole('Doctor', 'armadillo.organization.doctor'),
new NewRole('Nurse Practitioner', 'armadillo.organization.nursePractitioner'),
new NewRole('Patient', 'armadillo.microurb.billing'),
new NewRole('Microurb admin', 'armadillo.organization.admin'),
new NewRole('Microurb admin', 'armadillo.organization.admin'),
new NewRole('Microurb billing', 'armadillo.organization.billing'),
new NewRole('Respiratory therapist', 'armadillo.microurb.respiratoryTherapist'),
new NewRole('Microurb commercial contact', 'armadillo.microurb.practiceGrowthDirector')
];
var viewRoles = [];
for (var i = 0; i < armadilloRoles.length; i++) {
const role = armadilloRoles[i];
const viewRoleDto = new ViewRole(role.name, role.description);
// if (viewRoleDto[i].description.startsWith('armadillo.organization.')) {
// viewRoles.push(viewRoleDto[i]);
// }
viewRoles.push(viewRole);
}
console.log(viewRoles);
I have tried a variety of ways of implementing an if conditional with a startsWith() method.
I want to return just the ones that have armadillo.organization. as the description.
A good way would be to use reduce like this:
const matches = armadilloRoles.reduce(
(prev, cur) =>
cur.description.startsWith("armadillo.organization") ? [...prev, cur] : prev,
[]
);

How to skip last operation in recursive function?

There is a recursive function like this:
How do I exclude the last iteration and dont get last node in tree?
export function getFullName(treeNode: TreeNode, fullname = ''): string {
if (treeNode.parent) {
if (fullname) fullname = `${treeNode.name}/${fullname}`;
else fullname = treeNode.name;
fullname = getFullName(treeNode.parent, fullname);
}
return fullname;
}
Actually the reason you use tree Structure most of time because you want to make use of the structure and make searching easily.
You can use while loop to check if parent node exist instead of recursive.
class TreeNode {
constructor(id, name, treeNode) {
this.id = id;
this.name = name;
this.parent = treeNode === undefined ? null : treeNode;
}
}
const node1 = new TreeNode(1, "node1");
const node2 = new TreeNode(2, "node2", node1);
const node3 = new TreeNode(2, "node3", node2);
function getFullName(treeNode) {
let node = treeNode;
let fullName = "";
while (node) {
fullName = `${node.name}/${fullName}`;
node = node.parent;
}
return fullName;
}
const output = getFullName(node3);
console.log(output);

How to write a object oriented Node.js model

I am having a lot of trouble writing an object oriented Cat class in Node.js. How can I write a Cat.js class and use it in the following way:
// following 10 lines of code is in another file "app.js" that is outside
// the folder "model"
var Cat = require('./model/Cat.js');
var cat1 = new Cat(12, 'Tom');
cat1.setAge(100);
console.log(cat1.getAge()); // prints out 100 to console
var cat2 = new Cat(100, 'Jerry');
console.log(cat1.equals(cat2)); // prints out false
var sameAsCat1 = new Cat(100, 'Tom');
console.log(cat1.equals(sameAsCat1)); // prints out True
How would you fix the following Cat.js class I have written:
var Cat = function() {
this.fields = {
age: null,
name: null
};
this.fill = function (newFields) {
for(var field in this.fields) {
if(this.fields[field] !== 'undefined') {
this.fields[field] = newFields[field];
}
}
};
this.getAge = function() {
return this.fields['age'];
};
this.getName = function() {
return this.fields['name'];
};
this.setAge = function(newAge) {
this.fields['age'] = newAge;
};
this.equals = function(otherCat) {
if (this.fields['age'] === otherCat.getAge() &&
this.fields['name'] === otherCat.getName()) {
return true;
} else {
return false;
}
};
};
module.exports = function(newFields) {
var instance = new Cat();
instance.fill(newFields);
return instance;
};
If I were to design an object like this, then I would have done like this
function Cat(age, name) { // Accept name and age in the constructor
this.name = name || null;
this.age = age || null;
}
Cat.prototype.getAge = function() {
return this.age;
}
Cat.prototype.setAge = function(age) {
this.age = age;
}
Cat.prototype.getName = function() {
return this.name;
}
Cat.prototype.setName = function(name) {
this.name = name;
}
Cat.prototype.equals = function(otherCat) {
return otherCat.getName() == this.getName()
&& otherCat.getAge() == this.getAge();
}
Cat.prototype.fill = function(newFields) {
for (var field in newFields) {
if (this.hasOwnProperty(field) && newFields.hasOwnProperty(field)) {
if (this[field] !== 'undefined') {
this[field] = newFields[field];
}
}
}
};
module.exports = Cat; // Export the Cat function as it is
And then it can be used like this
var Cat = require("./Cat.js");
var cat1 = new Cat(12, 'Tom');
cat1.setAge(100);
console.log(cat1.getAge()); // 100
var cat2 = new Cat(100, 'Jerry');
console.log(cat1.equals(cat2)); // false
var sameAsCat1 = new Cat(100, 'Tom');
console.log(cat1.equals(sameAsCat1)); // true
var sameAsCat2 = new Cat();
console.log(cat2.equals(sameAsCat2)); // false
sameAsCat2.fill({name: "Jerry", age: 100});
console.log(cat2.equals(sameAsCat2)); // true
I would use a class :
class Cat {
fields = {
age: null,
name: null
};
fill(newFields) {
for(var field in this.fields) {
if(this.fields[field] !== 'undefined') {
this.fields[field] = newFields[field];
}
}
}
getAge() {
return this.fields.age;
}
setAge(newAge) {
this.fields.age = newAge;
}
}
exports.Cat = Cat;
This code is working fine Person.js code here
exports.person=function(age,name)
{
age=age;
name=name;
this.setAge=function(agedata)
{
age=agedata;
}
this.getAge=function()
{
return age;
}
this.setName=function(name)
{
name=name;
}
this.getName=function()
{
return name;
}
};
call object code:
var test=require('./route/person.js');
var person=test.person;
var data=new person(12,'murugan');
data.setAge(13);
console.log(data.getAge());
data.setName('murugan');
console.log(data.getName());
There is error loop hole in answers by #thefourtheye, I will describe those below
Object modelling rules
Create empty new object
Create Filled Object
Only Initial object should be set by machine/code
After Initial object assignment Any changes in your object should happen by user interaction only.
After Initial object assignment Any changes in object by code without user intention is going to add some bugs
Problem Use case :
Eg - So when you create filled object , at that time if any property(somedate) is not having any value then due to below code the default value gets assigned to it(somedate) , which is against object modelling rules.
Bug
Constructor function is given Dual responsibility to create new
& filled object which he mixes up while creating filled object , And
its going to make mistakes.
Means there is some buggy code in your app that is going to set values by it self without users intention
function Cat(age, name, somedate ) { // Accept name and age in the constructor this.name = name || null; this.age = age || null; this.somedate = somedate || new Date(); //there will be lots of usecases like this }
So to solve this Problem i use below JavaScript data model.
So it allows user to create filled object Or new object intentionally only when need any one of them and not messing with each other
class Cat {
constructor(){
this.name = null;
this.age = null;
}
initModel (data) {
this.name = data.name;
this.age = data.age
}
getAge () { return this.age;}
setAge (age) { this.age = age; }
getName () {this.name;}
setName (name) {this.name = name;}
equals (otherCat) {
return otherCat.getName() == this.getName()
&& otherCat.getAge() == this.getAge();
}
fill (newFields) {
for (let field in newFields) {
if (this.hasOwnProperty(field) && newFields.hasOwnProperty(field)) {
if (this[field] !== 'undefined') {
this[field] = newFields[field];
}
}
}
};
}
let cat1 = new Cat();
cat1.initModel({age : 12,name :'Tom'})
cat1.setAge(100);
console.log(cat1.getAge()); // 100
let cat2 = new Cat();
cat2.initModel({age : 100,name : 'Jerry'})
console.log(cat1.equals(cat2)); // false
let sameAsCat1 = new Cat({age : 100,name : 'Tom'});
sameAsCat1.initModel({age : 100,name : 'Tom'})
console.log(cat1.equals(sameAsCat1)); // true
let sameAsCat2 = new Cat();
console.log(cat2.equals(sameAsCat2)); // false
sameAsCat2.fill({name: "Jerry", age: 100});
console.log(cat2.equals(sameAsCat2));
Note :
Constructor is only used For creating new Object
InitModel is only used For creating filled Object

OO Javascript Game, how can i add players the game's player array?

Here is the beginning of a very simple object oriented javascript game. I am having trouble adding players to the Games players[] array. how can this be done?
i've removed all the code not relevant to the question
var BobsGame = function(){
this.Players = [];
}
BobsGame.prototype.addPlayer = function(Player){
//not working
Player.Game = this;
this.Players.push(Player);
Player.setId = function(this.Players.length) {
return this.Players.length;
}
return this;
}
var Player = function(name){
this.Game = null;
this.score = 0;
this.name = name;
this.id = null;
// return alert('Player ' + this.name + ' has been created');
}
var myGame = new BobsGame();
var Player1 = new Player("Tom");
var Player2 = new Player("Bob");
myGame.addPlayer(Player1);
What I think you're trying:
var BobsGame = function () {
this.Players = [];
};
BobsGame.prototype.addPlayer = function (Player) {
this.Players.push(Player);
Player.id = this.Players.length;
return this;
};
var Player = function (name) {
this.score = 0;
this.name = name;
this.id = null;
// return alert('Player ' + this.name + ' has been created');
};
var myGame = new BobsGame();
var Player1 = new Player("Tom");
var Player2 = new Player("Bob");
myGame.addPlayer(Player1);
The error was in the following code:
Player.setId = function(this.Players.length) {
return this.Players.length;
}
Here you're trying creating a function called setId, but you can't define this.Players.length as an argument. So assuming you're trying to set the id of the player to the length of the players array, you can simple assign it like this:
Player.id = this.Players.length;
By the way, I do recommend you don't call the argument of addPlayer "Player" since this will hide the already defined function Player. You might want to rename it to "player".

Compare the classes of 2 separate JavaScript objects

I want to compare the classes of 2 JavaScript objects. The current call below fails. The idea here is to deal extract the correct cross-rate using the passed-in "from and to" variables.
Thanks for the help!
UPDATED: The Working Code Now Looks Like This:
<script type="text/javascript">
<!--
// ------------------------
// CLASS
function Currency(clientId, country, code, imageURL, name) {
this.clientId = clientId //EXAMPLE: txtBudget
this.country = country; //EXAMPLE: America
this.code = code; //EXAMPLE: USD
this.imageURL = imageURL; //EXAMPLE: "http://someplace/mySymbol.gif"
this.name = name; //EXAMPLE: Dollar
this.amount = parseFloat("0.00"); //EXAMPLE: 100
};
Currency.prototype.convertFrom = function (currency, factor) {
this.amount = currency.amount * factor;
}
// CLASS
function Pound(clientId, imageURL) {
Currency.call(this, clientId, "Greate Britain", "GBP", imageURL, "Pound");
};
Pound.prototype = new Currency();
Pound.prototype.constructor = Pound;
// CLASS
function Dollar(clientId, imageURL) {
Currency.call(this, clientId, "America", "USD", imageURL, "Dollar");
};
Dollar.prototype = new Currency();
Dollar.prototype.constructor = Dollar;
// CLASS
function Reais(clientId, imageURL) {
Currency.call(this, clientId, "Brazil", "BRL", imageURL, "Reais");
};
Reais.prototype = new Currency();
Reais.prototype.constructor = Reais;
// ------------------------
// CLASS
function Suscriber(element) {
this.element = element;
};
// CLASS
function Publisher() {
this.subscribers = new Array();
this.currencyCrossRates = new Array();
};
Publisher.prototype.findCrossRate = function (from, to) {
var crossRate = null;
for (var i = 0; i < this.currencyCrossRates.length; i++) {
if ((this.currencyCrossRates[i].from.constructor === from.constructor) && (this.currencyCrossRates[i].to.constructor === to.constructor))
crossRate = this.currencyCrossRates[i];
}
return crossRate;
}
// ------------------------
// CLASS
function CurrencyCrossRate(from, to, rate) {
this.from = from;
this.to = to;
this.rate = parseFloat(rate);
};
jQuery(document).ready(function () {
var dollar = new Dollar(null, null);
var reais = new Reais(null, null);
var dollarToReais = new CurrencyCrossRate(dollar, reais, 0.8);
var reaisToDollar = new CurrencyCrossRate(reais, dollar, 1.2);
publisher = new Publisher();
publisher.currencyCrossRates.push(dollarToReais);
publisher.currencyCrossRates.push(reaisToDollar);
// SETUP
jQuery(".currency").each(function () {
publisher.subscribers.push(new Suscriber(this));
});
var newDollar = new Dollar(null, null);
var newReais = new Reais(null, null);
// This now resolves correctly
var first = crossRate = publisher.findCrossRate(newDollar, newReais);
var second = crossRate = publisher.findCrossRate(newReais, newDollar);
});
-->
</script>
The right hand side operator of instanceof should not be the prototype object, but instead the object's constructor function, accessible through the constructor property of the object in question. Since this property in fact references the function which was used to construct the object, comparison is done with the usual equality operator:
this.currencyCrossRates[i].from.constructor == from.constructor
EDIT:
Remove the lines Pound.prototype.constructor = Pound(); etc (one for each currency). The constructor property is a built-in feature which automatically references the correct function. However, it is unfortunately writable and so can be reassigned - don't do it!
The conditions should be of the form this.currencyCrossRates[i].from instanceof from.constructor - the left operand is the Object and the right one is the constructor function.

Categories

Resources