Using function of an object after grabbing it from array - javascript

When I try to grab the object from the array, the type is undefined. Therefore I cannot use a method from the undefined object as it doesn't exist. I am relatively new to JavaScript and I have come straight from Java so the way of retrieving objects is kind of new to me. This is what I currently have.
var fleetAmount = 0;
var fleets = [];
function Fleet(number) {
this.number = number;
this.activities = [];
this.addActivity = function (activity) {
this.activities.push(activity);
};
fleets.push(this);
}
var getFleet = function(fleetNumber) {
return fleets[fleetAmount - fleetNumber];
}
This is where I try to grab the object and preform the function
const Fl = require(‘fleet.js’);
const fleet = Fl.getFleet(fleetNumber);
fleet.addActivity(activity);
I am also working in Node.js, which is how I am using the require method.

In combination with the answer from #audzzy I changed the getFleet() function so that it would be more efficient. I tested it out and it worked. This is what I used
function getFleet(fleetNumber) {
let result = fleets.filter(function (e) {
return e.number = fleetNumber;
})
return result[0];
}
Thanks for the help! I appreciate it.

you want to create a new fleet object and add it, not "this"..
adding "this" would cause a circular reference, where
this.fleets[i] = this (and all fleets would have the same value)
when calling get fleet, I would check that a fleet was returned from get fleet
in case amount is less than the number you send to getFleet (where according to what you posted: 1 returns the last, 2 returns second to last etc..)..
I hope this explanation makes sense.. anyways, this should work..
var fleets = [];
doStuff();
function doStuff(){
addFleet(1);
addFleet(2);
addFleet(7);
addFleet(3);
// should return null
let fleet1 = getFleetByNumber(5);
// should return the fleet with number 7, and not change the fleet with number 1
let fleet2 = getFleetByNumber(7);
if(fleet2){
fleet2.addActivity("activity");
}
console.log(`fleets: ${JSON.stringify(fleets)} \nfleet1: ${JSON.stringify(fleet1)} \nfleet2: ${JSON.stringify(fleet2)}`);
}
function addFleet(number) {
let fleet = { number: number,
activities: [] };
fleet.addActivity = function (activity) {
this.activities.push(activity);
};
fleets.push(fleet);
}
function getFleetByNumber(fleetNumber) {
return fleets.find(function (e) {
return e.number == fleetNumber;
});
}
function getFleet(fleetNumber) {
let result = null;
if(fleets.length - fleetNumber >= 0){
result = fleets[fleets.length - fleetNumber];
}
return result;
}

Related

Which type of variable is created in the code below

In the code below is an iterator:
const cart = ['Product 0','Product 1','Product 2','Product 3','Product 4','Product 5','Product 6','Product 7','Product 8','Product 9','Product 10']
function createIterator(cart) {
let i = 0;//(*)
return {
nextProduct: function() {
//i:0; (**)
let end = (i >= cart.length);
let value = !end ? cart[i++] : undefined;
return {
end: end,
value: value
};
}
};
}
const it = createIterator(cart);
First I know a copy of the present state of the function's variables and the parameters are parsed.(Right?)...
And when you run
const it = createIterator(cart);
Is a property below created?
//i:0 (**);
Making it.next(); equivalent to
{
i:0;//state or value of i from createIterator() definition;
next : function(cart){
let end = (this.i >= cart.length);
let value = !end ? cart[this.i++] : undefined;
return {
end: end,
value: value
};
}
Or does state of the value of i in line (*) from the first code, Is what's what is modified?
Please if this point is not clear... let me know to explain better.
Calling the iterator will create an instance of i scoped to the createIterator function. The object returned from it will only have access to that specific instance of i, but i is not a property of the object returned. It only can access it due to the function scope.
You can see a little better how this works if we break your code down a little more simply:
function createIterator(cart, display) {
let i = 0;
return {
next: function() {
i++;
console.log(display + ' next: ', i);
}
};
}
const cart1 = [];
const cart2 = [];
const it1 = createIterator(cart1, 'cart1');
it1.next();
it1.next();
const it2 = createIterator(cart2, 'cart2');
it2.next();
it2.next();
Each instance of the iterator has a different copy of i and only the object returned from the iterator function can access it.

How to use recursion in JavaScript for try do function?

I want to make this code prettier with recursion.
findModel = function(oldModel, ...modelStyles) {
let model = oldModel.elements;
let i = 0;
try {
do {
model = model.children.find(child => child.mStyle === modelStyles[i]);
i += 1;
} while (i < modelStyles.length);
return model;
} catch (e) {
return undefined;
}
};
tried this:
findModel = function(oldModel, ...modelStyles) {
let model = oldModel.elements;
let i = 0;
if (i < modelStyles.length) {
model = model.children.find(child => child.mStyle === modelStyles[i]);
i += 1;
return model;
} else {
return undefined;
}
};
but it's still not working well. in the first code I get only the element, in the second one I get also undefined.
What did I wrong?
As amply noted in comments, you are actually never calling the function recursively.
When it comes to "pretty", I would not go for recursion, but for reduce:
var findModel = function(oldModel, ...modelStyles) {
try {
return modelStyles.reduce((model, style) => model.children.find(child => child.mStyle === style), oldModel.elements);
} catch (e) {} // No need to explicitly return undefined. It is the default
};
If you really need recursion, then first realise that your function expects a first argument type that never occurs again. Only the toplevel model has an elements property, so you can only call this function for ... the top level of your hierarchy.
To make it work, you would need another function that takes the model type as it occurs in the children:
var findModel = function(oldModel, ...modelStyles) {
function recur(model, style, ...modelStyles) {
if (style === undefined) return model;
return recur(model.children.find(child => child.mStyle === style), ...modelStyles);
}
// Need to change the type of the first argument:
try {
return recur(oldModel.elements, ...modelStyles);
} catch (e) {}
};
If you would change the code where the function is called initially, you could of course pass mainmodel.elements instead of mainmodel, so that this type difference problem is resolved. If you can make that change, then the recursive function can become:
var findModel = function(model, style, ...modelStyles) {
if (style === undefined) return model;
try {
return recur(model.children.find(child => child.mStyle === style), ...modelStyles);
} catch (e) {}
};
Still, I would prefer the reduce variant.
The point of recursive function is to call themselves into themselves. In your case, you are calling the function once, but the function never call itself so it just go through once. I'm not sure of the context so I can't fix your code but i can give you an example of recursion.
Lets say we have an object with property. Some are string, some are number and some are objects. If you want to retrieve each key of this object you would need recursion, since you don't know how deep the object goes.
let objectToParse = {
id: 10,
title: 'test',
parent: {
id: 5,
title: 'parent',
someKey: 3,
parent: {
id: 1,
title: 'grand-parent',
parent: null,
someOtherkey: 43
}
}
};
function parseParentKey(object) {
let returnedKey = [];
let ObjectKeys = Object.keys(object);
for(let i = 0; i < ObjectKeys.length; i++) {
if(typeof object[ObjectKeys[i]] === "object" && object[ObjectKeys[i]] !== null) {
// we are calling the methode inside itself because
//the current property is an object.
returnedKey = returnedKey.concat(parseParentKey(object[ObjectKeys[i]]));
}
returnedKey.push(ObjectKeys[i]);
}
return returnedKey;
}
console.log(parseParentKey(objectToParse));
I know this does not answer your question but it gives you a hint on how to use recursion properly. If your first code works, I don't see why you would need to change it in the first place.

How can I make this return, return a number and not one function?

I am currently working on one new card game. I have one array full of numbers. I also have one object with a lot of functions, everytime I run mij object function it returns one function and not the first number from the array can anyone please help me?
Array: (Yeah a very complicated way to create one array with 4 times every numer between 1 and 10)
var cardDatabase = createDeck([].concat.apply([], new Array(10).fill().map((_, k) => new Array(4).fill(k + 1))))
Object + function:
function createDeck (array) {
var cardDatabase = array
return {
peek: function () {
return cardDatabase[cardDatabase.length - 1]
},
}
}
Are you looking for something like this?
var createDeck = function () {
this.cardDatabase = [1,2,3,4,5,6,7,8,9,10];
this.peek = function () {
return this.cardDatabase[this.cardDatabase.length - 1];
};
return this;
}
and (new createDeck).peek();

Javascript: Getting the newest array

I've been thinking about how to display the newest array (because the array list would update from time to time.). I think there's a default function to it but I can't find it. Anyone knows it?
var bgImg = new Array();
bgImg[0] = "background.jpg";
bgImg[1] = "background2.jpg";
bgImg[2] = "background3.jpg";
bgImg[3] = "background4.jpg";
If you want the last element of the array,
>>> a = ['background1','background2'];
["background1", "background2"]
>>> b = a[a.length-1]
"background2"
You shouldn't need to manually assign indexes. Just do bgImg.push('background2.jpg'), and it will mutate the array for you. In your case the syntax would be...
var last = bgImg[bgImg.length-1]
If you want the newest then you need to make a variable and set it with whatever you update when you push the newest one, if it doesn't become the last one.
You could create a little object to handle this for you.
function creatImageState() {
var images = [];
return {
get latest() {
return images[images.length - 1];
},
set latest (value) {
images.push(value);
}
};
}
var s = creatImageState();
s.latest = "a.png";
s.latest = "b.png";
alert(s.latest);
IE doesn't support getters and setters so you probably need to use this.
function creatImageState() {
var images = [];
return {
getLatest : function() {
return images[images.length - 1]
},
setLatest : function(value) {
images.push(value);
}
};
}
var s = creatImageState();
s.setLatest("a.png");
s.setLatest("b.png");
alert(s.getLatest());

How can I pass results from a callback via an object?

I am performing a Google local search, and wish to return the lat/long via an object.
The Google search itself works fine.
When inspected (using console.log or alert()) in the object itself, the results field appears to be populated OK.
However, when inspecting the instance of the object (instantiated before running the callback) the result is blank. I'm aware I don't need the accessor function - the end result is the same either way.
Is there something fundamental missing here? Thanks!
function GeoSearch() {
this.results = [];
this.searchComplete = function(localSearch) {
if(localSearch.results[0]) {
var resultLat = localSearch.results[0].lat;
var resultLng = localSearch.results[0].lng;
this.results = localSearch.results[0].lat;
}
}
this.getResults = function() {
return this.results;
}
}
function populateCoords(postcode) {
var localSearch = new google.search.LocalSearch();
var gs = new GeoSearch();
localSearch.setSearchCompleteCallback(gs, gs.searchComplete, [localSearch]);
localSearch.execute(postcode + ", UK");
alert(gs.getResults());
}
When you reference the function gs.searchComplete, you're detaching the method from the object it belongs to. Switch it to function () { gs.searchComplete(); }

Categories

Resources