How to make a "getParent" function in a Javascript file directory - javascript

I'm making a file system, but can't figure out how to add a "parent" property.
currently I think my issue is that I can't call a function that hasn't been declared yet, but I don't see how to escape this circular logic then.
the current error is:
Uncaught TypeError: inputDir.getParentDirectory is not a function
and my code is:
var file = function(FileName,inputDir,isDir){
this.Name=FileName;
this.CurrentDir=inputDir;
this.isDirectory = isDir;
this.size = 0;
this.timeStamp = new Date();
if(isDir===true){
this.subfiles = [];
}
if(inputDir!==null){
this.parentDir = inputDir.getParentDirectory();
}
this.rename = function(newName){
this.Name = newName;
};
this.updateTimeStamp = function(){
this.timeStamp = new Date();
};
};
file.prototype.getParentDirectory = function(){
return this.parentDir;
};
var fileSystem = function(){
this.root = new file("root",null,true);
this.createFile = function(name,currentDirectory,isDirectory){
var f = new file(name,currentDirectory,isDirectory);
currentDirectory.subfiles.push(f);
};
};
var myComputer = new fileSystem();
myComputer.createFile("Desktop","root",true);

You are passing a string to inputDir which causes the error you are seeing since the getParentDirectory() method is defined for file prototype, not string. Instead you need to pass in an instance of file. Another option would be to write code to lookup an instance of file by string.
var file = function(FileName,inputDir,isDir){
this.Name=FileName;
this.CurrentDir=inputDir;
this.isDirectory = isDir;
this.size = 0;
this.timeStamp = new Date();
if(isDir===true){
this.subfiles = [];
}
if(inputDir!==null){
this.parentDir = inputDir.getParentDirectory();
}
this.rename = function(newName){
this.Name = newName;
};
this.updateTimeStamp = function(){
this.timeStamp = new Date();
};
};
file.prototype.getParentDirectory = function(){
return this.parentDir;
};
var fileSystem = function(){
this.root = new file("root",null,true);
this.createFile = function(name,currentDirectory,isDirectory){
var f = new file(name,currentDirectory,isDirectory);
currentDirectory.subfiles.push(f);
};
};
var myComputer = new fileSystem();
myComputer.createFile("Desktop",myComputer.root,true);
console.log("myComputer:", myComputer);
console.log("Desktop:", myComputer.root.subfiles[0]);

Related

I have a mapping method that accepts a callback as an argument but I keep getting this error JavaScript

I'm totally confused as to why 'cb' is not a function in my case.
Basically I have a 'Tree' constructor
this.value = value;
this.children = [];
};
Tree.prototype.addChild = function (value){
var newInstance = new Tree(value);
this.children.push(newInstance);
}
Tree.prototype.map = function(cb){
var copyTree = new Tree(this.value); //1
copyTree.value = cb(copyTree.value);
for (var i = 0; i < this.children.length; i++){ // i = 0; 2 i = 0's value is 2
copyTree.addChild(new Tree.prototype.map(cb(this.children[i].value)))
}
return copyTree;
}
and then in the console I've passed in
var root1 = new Tree(1)
var branch1 = root1.addChild(2);
var branch2 = root1.addChild(3);
Now every time I invoke
var newTree = root1.map(function (value) {
return value * 2 })
I keep getting this error.
VM1769 Script snippet %231:13 Uncaught TypeError: cb is not a function
at new Tree.map (VM1769 Script snippet %231:13)
at Tree.map (VM1769 Script snippet %231:19)
at <anonymous>:1:21
I know that my mapping method might not be right but just the fact that 'cb' is not a function confuses me, I'm passing in an anonymous function on the .map call but.. 'cb' is not a function? Why is that?
Inside .map, you have an array of trees to copy inside this.children. Since the array is composed of trees, those trees already have a .map method which you can call to create a copy of that tree. Change
copyTree.addChild(new Tree.prototype.map(cb(this.children[i].value)))
to
copyTree.addChild(this.children[i].map(cb))
function Tree(value) {
this.value = value;
this.children = [];
};
Tree.prototype.addChild = function(value) {
var newInstance = new Tree(value);
this.children.push(newInstance);
}
Tree.prototype.map = function(cb) {
var copyTree = new Tree(this.value);
copyTree.value = cb(copyTree.value);
for (var i = 0; i < this.children.length; i++) {
copyTree.addChild(this.children[i].map(cb))
}
return copyTree;
}
var root1 = new Tree(1)
var branch1 = root1.addChild(2);
var branch2 = root1.addChild(3);
var newTree = root1.map(function(value) {
return value * 2
})
console.log(newTree);
More readably, using modern syntax:
class Tree {
constructor(value) {
this.value = value;
this.children = [];
}
addChild(value) {
const newInstance = new Tree(value);
this.children.push(newInstance);
}
map(cb) {
const copyTree = new Tree(this.value);
copyTree.value = cb(copyTree.value);
for (const child of this.children) {
copyTree.addChild(child.map(cb))
}
return copyTree;
}
}
const root1 = new Tree(1)
const branch1 = root1.addChild(2);
const branch2 = root1.addChild(3);
const newTree = root1.map(value => value * 2);
console.log(newTree);

Use the value of a variable in another file

Currently I am using protractor and using page object, so there is a file that I get the value of an element in a variable, but I need to call this value in another file.
vehiclePage.js
/*jshint esversion: 6 */
var basePage = require('./basePage.js');
var homePage = require('./homePage.js');
var VehiclePage = function() {
this.storeVehicleData = function() {
this.pessengersRuntValue = element(by.id('preview_ocupantes_runt')).getText();
};
};
VehiclePage.prototype = basePage; // extend basePage...
module.exports = new VehiclePage();
Now I need to use the value of the above variables in another file
checkoutPage.js
/*jshint esversion: 6 */
var basePage = require('./basePage.js');
var homePage = require('./homePage.js');
var CheckoutPage = function() {
this.getRuntValue = element(by.css('.mb10'));
this.compareValues = function() {
expect(this.getRuntValue.getText()).toContain(this.pessengersRuntValue);
};
};
CheckoutPage.prototype = basePage; // extend basePage...
module.exports = new CheckoutPage();
How can I make it work?
If you are following Page Object Design Pattern, I would say that the test should not be on the page object. I will write something like this.
VehiclePage.js
var VehiclePage = function(){
// if this is a browser testing something like this
browser.get('/vehicle');
};
VehiclePage.prototype = Object.create({}, {
runt: {
get: function(){
return element(by.id('preview_ocupantes_runt'));
}
}
});
module.export = VehiclePage;
CheckOutPage.js
var CheckOutPage = function(){
// if this is a browser testing something like this
browser.get('/checkout');
};
CheckOutPage.prototype = Object.create({}, {
runt: {
get: function(){
return element(by.css('.mb10'));
}
}
});
module.export = CheckOutPage;
TheTest.js
var VehiclePage = require('VehiclePage');
var CheckOutPage = require('CheckOutPage');
describe('testing something', () => {
var vehicle = new VehiclePage();
var checkout = new CheckOutPage();
it('should contain', () => {
expect(checkout.runt.getText()).toContains(vehicle.runt.getText());
});
});
One way to do this would be to pass a state object to both pages.
var VehiclePage = require('./vehiclePage.js');
var CheckoutPage = require('./checkoutPage.js');
class StateStorage {
constructor(){
this.savedVariable = null;
}
}
var state = new StateStorage();
var vehiclePage = new VehiclePage(state);
var checkoutPage = new CheckoutPage(state);
Then you can manipulate and access the state from both new pages.

Javascript: Calling private in a outside javascript file with JSON data

I am trying to call the method getTitulo, getDuracion and getLink inside the cancion.js file but when i call the function it returns the following error: "listaCanciones_Lcl[i].getTitulo is not a function". I have searched in different websites but i didnt got lucky with finding an answer. Hopefully someone here can give me some help, i will gladly appreciate it!
//Logic.js file
var listaCanciones = [],
ejecuTitulo = '',
ejecuDuracion = '',
ejecuLink = '';
var btnGenerarLista = document.getElementById("addList").addEventListener("click", agregarCanc);
var btnAgregarLista = document.getElementById("gnrList").addEventListener("click", llenarTabla);
function agregarCanc (){
var nameSong = document.querySelector('#nameSong').value;
var duraSong = document.querySelector('#duraSong').value;
var linkSong = document.querySelector('#linkSong').value;
var objCancion = new Cancion(nameSong, duraSong, linkSong);
listaCanciones.push(objCancion);
var listaCancionesJson = JSON.stringify(listaCanciones);
localStorage.setItem('json_canciones', listaCancionesJson);
}
function llenarTabla (titulo){
var celdaTitulo = document.querySelector('#tituloList'),
celdaDuracion = document.querySelector('#duracionList'),
celdaLink = document.querySelector('#linkList'),
listaCanciones_Lcl = JSON.parse(localStorage.getItem('json_canciones'));
for(var i=0; i<listaCanciones_Lcl.length;i++){
// Acceder a lista canciones
I am getting an error in this line, where is says "getTitulo" is not a function but i dont really know why?
var nodoTextoTitulo = document.createTextNode(listaCanciones_Lcl[i].getTitulo()),
nodoTextoDuracion = document.createTextNode(listaCanciones_Lcl[i].getDuracion()),
nodoTextoLink = document.createTextNode(listaCanciones_Lcl[i].getLink());
// Create td
var elementoTdTitulo = document.createElement('td'),
elementoTdDuracion = document.createElement('td'),
elementoTdLink = document.createElement('td');
// Celda Id Append Child
elementoTdTitulo.appendChild(nodoTextoTitulo);
elementoTdDuracion.appendChild(nodoTextoDuracion);
elementoTdLink.appendChild(nodoTextoLink);
// Fila Append Child
celdaTitulo.appendChild(elementoTdTitulo);
celdaDuracion.appendChild(elementoTdDuracion);
celdaLink.appendChild(elementoTdLink);
}
}
//Cancion.js File
var Cancion = function(pTitulo, pDuracion, pLink){
var id = 0;
var titulo = pTitulo;
var duracion = pDuracion;
var link = pLink;
this.getId = function (){
return id;
};
this.setTitulo = function (pTitulo){
titulo = pTitulo;
};
this.getTitulo = function(){
return titulo;
};
this.setDuracion = function(pDuracion){
duracion = pDuracion;
};
this.getDuracion = function(){
return duracion;
};
this.setLink = function (pLink){
link = pLink;
};
this.getLink = function(){
return link;
};
};
First, make sure you are loading the Cancion.js file before the others in your HTML. Your problem is that when you parse the JSON back out of local storage, Cancion is not a known object, so getTitulo is undefined. You'll have to do listaCanciones_Lcl[i].titulo; instead.
And another change you'll need is to loosen the scope of your variables. The reason you need this.x = pX is because before JSON.stringify(new Cancion(1, 2, 3)) just returned "{}". With this code it returns "{"id":0,"titulo":1,"duracion":2,"link":3}", which I think is what you were after.
function Cancion(pTitulo, pDuracion, pLink){
this.id = 0;
this.titulo = pTitulo;
this.duracion = pDuracion;
this.link = pLink;
this.getId = function (){
return this.id;
};
this.setTitulo = function (pTitulo){
this.titulo = pTitulo;
};
this.getTitulo = function(){
return this.titulo;
};
this.setDuracion = function(pDuracion){
this.duracion = pDuracion;
};
this.getDuracion = function(){
return this.duracion;
};
this.setLink = function (pLink){
this.link = pLink;
};
this.getLink = function(){
return this.link;
};
};
var objWithFunction = {
name: 'Object with Function',
getName: function() { return this.name }
};
undefined
objWithFunction.getName() // --> "Object with Function"
var string = JSON.stringify(objWithFunction)
string // -=> "{"name":"Object with Function"}"
JSON is for data only..
Better you create a model, and fill it with data.. but this model has to exist in your application.. or you load the model parallel to your data..
function SomeThing() {};
SomeThing.prototype.getName = function() { return this.name };
var Thing1 = new SomeThing(JSON.parse("{name:'ThingOne'}"));
Thing1.getName(); // ThingOne

javascript inheritance - '...is not defined'. Namespace issue?

I have a 'class' called ModuleSelector that grabs a list of modules from a server and displays them as clickable toggle buttons. I'm trying to create a class called Module that extends the ToggleButton class and is only visible to the ModuleSelector.
The problem I'm having is that the line:
Module.prototype = new ToggleButton(); is giving an error: ToggleButton is not defined.
I don't understand why it cannot be found, because I can create new instances of ToggleButton inside the Module function, for example.
ModuleSelector.js
(function() {
function Module(id,name){
this.moduleID = id;
this.moduleName = name;
this.topics = [];
this.addTopic = function(topic){
this.topics.push(topic);
}
}
Module.prototype = new ToggleButton();
Module.prototype.constructor = Module;
var ModuleSelector = function (id) {
this.initialize(id);
};
var p = ModuleSelector.prototype = new createjs.Container();
p.Container_initialize = p.initialize;
p.initialize = function (id) {
this.Container_initialize();
//.....
};
window.ModuleSelector = ModuleSelector;
}());
ToggleButton.js
(function() {
var ToggleButton = function(text) {
this.initialize(text);
//....code
};
var p = ToggleButton.prototype = new createjs.Container();
p.Container_initialize = p.initialize;
p.initialize = function(text) {
this.Container_initialize();
};
window.ToggleButton = ToggleButton;
}());

Creating a simple constructor for a grouping of Web Audio API nodes

I have a batch of Web Audio API nodes that look like the code below. I want to abstract this into a simple constructor but I'm having trouble. I'm not sure what I'm doing wrong. The end result should look something like
function filterTemplate(name,freqVal){
this.name = context.createBiquadFilter();
this.name.type = 5;
this.name.gain.value = null;
this.name.Q.value = 1;
this.name.frequency.value = this.freqVal; // freqVal is here
}
When I call the function:
var filter = new filterTemplate("theName",200); //Uncaught TypeError: Cannot call method 'createBiquadFilter' of undefined
I changed the method to look like this and the error is removed
this.name = function(){return context.createBiquadFilter()};
but then I get another error for the various property values
//Uncaught TypeError: Cannot set property 'value' of undefined
I'm really just confused as to the proper way to create a vanilla constructor using built in browser methods and properties.
I want to abstract the code below into looking something like the code above
filter1 = context.createBiquadFilter();
filter1.type = 5;
filter1.gain.value = null;
filter1.Q.value = 1;
filter1.frequency.value = 80; // Changes
filter2 = context.createBiquadFilter();
filter2.type = 5;
filter2.gain.value = 0;
filter2.Q.value = 1;
filter2.frequency.value = 240; // Changes
filter3 = context.createBiquadFilter();
filter3.type = 5;
filter3.gain.value = 0;
filter3.Q.value = 1;
filter3.frequency.value = 750; // Changes
filter4 = context.createBiquadFilter();
filter4.type = 5;
filter4.gain.value = 0;
filter4.Q.value = 1;
filter4.frequency.value = 2200; // Changes
filter5 = context.createBiquadFilter();
filter5.type = 5;
filter5.gain.value = 0;
filter5.Q.value = 1;
filter5.frequency.value = 6000; // Changes
The builder pattern is very nice for this situation. Especially when you can set a lot of properties.
http://jsfiddle.net/yw8Fm/
You can create a simple FilterTemplate class like this.
function FilterTemplate(builder) {
this.context = builder._context;
this.context.type = builder._type;
this.context.gain.value = builder._gainValue;
this.context.Q.value = builder._qValue;
this.context.frequency.value = builder._frequencyValue;
}
It takes a builder object as constructor argument. Here is the Builder.
FilterTemplate.Builder = function () {
this._context = context.createBiquadFilter();
this._type = 5;
this._gainValue = null;
this._qValue = 1;
this._frequencyValue = 80;
this.context = function (val) {
this._context = val; return this;
};
this.type = function (val) {
this._type = val; return this;
};
this.gainValue = function (val) {
this._gainValue = val; return this;
};
this.qValue = function (val) {
this._qValue = val; return this;
};
this.frequencyValue = function (val) {
this._frequencyValue = val; return this;
};
};
You can further extend this example as you like.
Now you can create FilterTemplates with ease.
var filter1 = new FilterTemplate(
(new FilterTemplate.Builder()).frequencyValue(80)
);
var filter2 = new FilterTemplate(
(new FilterTemplate.Builder()).frequencyValue(80).qValue(2)
);
Your problem is with the scope of your context variable.
var filter = new filterTemplate("theName",200); //Uncaught TypeError: Cannot call method 'createBiquadFilter' of undefined
... means that the context variable isn't available from where you're trying to reach it (which is within the filterTemplate constructor). When you do...
this.name = function(){return context.createBiquadFilter()};
... you're assigning the function to this.name instead, and it won't try to access the context until the function is run, and thus the error is removed. What happens instead is that you don't have a filter in this.name, but rather a function, and a function doesn't have a gain property and therefore you get an error when you try to set this.name.gain.value.
What you should look for is where you define the context, and make sure it's possible to access that variable from within filterTemplate.

Categories