2

I have a class and then defined an array of class, each time that I want to add a node to array, I have to mention the class name that I don't like it:

export class ItemModel {
  constructor(
    ID,
    Name
  ) {
    this.ID = ID;
    this.Name = Name; 
  }
}

export var ItemsArray = [];

ItemsArray.push(new ItemModel(0, "BreakFast"));
ItemsArray.push(new ItemModel(1, "Lunch"));
ItemsArray.push(new ItemModel(2, "Dinner"));

After reading this post:

https://answers.unity.com/questions/637902/how-to-use-javascript-array-with-classes.html

I tried to declare the class at the time that I define the array like this:

var ItemsArray : ItemModel[];

but I get error : "Types Can only be used in .ts files.

I searched google for that but none of them was helpful.

Any recommendation would be appreciated.

3
  • javascript's arrays aren't strongly typed. you could add a function that hides the construction and pushing. Commented May 30, 2019 at 15:05
  • var PanelItemsArray : PanelItem[]; is TypeScript syntax and you need a TypeScript compiler to turn it back to JavaScript. But even then, you don't solve your basic problem, since even in TS you'd need to do ItemsArray.push(new PanelItem(0, "BreakFast")); - all TS would provide you with is an error if you have ItemsArray.push(42); in your code, since 42 is a number, and not ItemModel Commented May 30, 2019 at 15:07
  • @T.J.Crowder, Sorry It was because of copying parts of my source, I edited that Commented May 30, 2019 at 15:15

2 Answers 2

4

The post you've linked to is using TypeScript, which is a different language from JavaScript: It's a superset of JavaScript (which compiles to JavaScript) that adds static typing (and a couple of other features, like automatic property initialization in constructors).

This TypeScript line:

var ItemsArray : ItemModel[];

is equivalent to this JavaScript:

var ItemsArray;

It's just that the TypeScript version declares that the ItemsArray variable has the static type ItemModel[].

If you're using JavaScript itself, you don't define the types of variables. Your export var ItemsArray = []; is just fine (other than that I'd use let or const instead of var).


Side Note: You can write that array more concisely in JavaScript using an array initializer:

export const ItemsArray = [
    new ItemModel(0, "BreakFast"),
    new ItemModel(1, "Lunch"),
    new ItemModel(2, "Dinner")
];

That's also valid TypeScript, even without a type declaration: TypeScript will infer that you want the type of ItemsArray to be ItemModel[] (because TypeScript does type inference and it can see that you're filling ItemsArray with ItemModel objects).

If you wanted to start with an empty array but still give it a static type, you'd do this:

//                                   /------ Telling TypeScript to use ItemModel[]
//                      vvvvvvvvvvvvv        as the type
export const ItemsArray : ItemModel[] = [];
//                                   ^^^^^-- Initializing ItemsArray with an
//                                           empty array

Then your push calls would be typechecked, so this would work:

ItemsArray.push(new ItemModel(0, "BreakFast"));

but this would cause an error (during TypeScript->JavaScript compilation)

ItemsArray.push("BreakFast");

because "Breakfast" is not compatible with ItemModel.


Side Note 2: The overwhelming convention in JavaScript (and TypeScript) is that variables start with a lowercase letter, not an uppercase one. So itemsArray rather than ItemsArray.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your comment and sorry for my edits after your answer, I has mistakenly used PanelItem in parts of above sample code and I changed it to ItemModel later. You are right , I am using react type script.I cant use array initializer as nodes will be added at run time after user actions.
@albertsh - I've updated the answer to handle the change in the question (and also to address the issue of not being able to add the entries until later, though that was a bit of a coincidence :-) ).
Appreciate for your time and advices ;)
2

Another alternative is to create a class that holds your items and make a method to add/remove them. This way, you won't have to new up your array items everytime. ...Well, you will. You just don't have to do it, the code will.

class ItemModel {
  constructor(id, name) {
    this.id = id;
    this.name = name;
  }
}

class ItemModelCollection {
  constructor() {
    this.items = [];
  }
  addItem(id, name) {
    if (Array.isArray(this.items)) {
      this.items.push(new ItemModel(id, name));
    }
  }
  removeItem(id) {
    if (Array.isArray(this.items)) {
      this.items = this.items.filter( i => i.id !== id);
    }
  }
}

const itemCollection = new ItemModelCollection();
document.getElementById('addItem').onclick = (e) => {
  const id = itemCollection.items.length; // obviously figure out a better id generator
  itemCollection.addItem(id, `Item Number ${id}`);
  console.log(itemCollection);
};
<button id="addItem">Add Item</button>

I should also note that not doing new ItemModel(id, name) and doing the mentioned typescript way (<ItemModel>{ id: id, name: name}) is fine, but if the class has methods, they will not work since you are not 'newing it up'. If you just set the properties without initializing the class, you essentially lose the point of having the class.

Related/Explantion for the pattner/issues with classes (not really angular specific like the article says): Angular : Class and Interface

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.