7

I am trying to declare an object and to set the default values in my ionic 2 app, but I don't understand TypeScript and Angular2 very well yet.

I did this:

@Component({
    selector: 'page-weightlevel'
    , templateUrl: 'weightlevel.html'
})
export class WeightlevelPage {

    name: string;
    firstNavParam: boolean;
    data = any;
    data.shareoptions: ['Facebook', 'Twitter', 'Email'];
    data.techniqueText: string;
    data.frequScaleWording: string[];
    data.fitnessWording: string[];
    data.levelName: string[];

    constructor(
        public navCtrl: NavController,
        ....

and I get this error:

Typescript Error
';' expected.
src/pages/weightlevel/weightlevel.ts
data.shareoptions: ['Facebook', 'Twitter', 'Email'];

the dot between data and shareoptions is not welcome apparently.

How can I do this?

halfer
  • 19,824
  • 17
  • 99
  • 186
Louis
  • 2,548
  • 10
  • 63
  • 120

5 Answers5

14

The way to declare/initialize an Object in Typescript is, is by like name says, typing your data. You could go with any, but that just defies the purpose of TypeScript. So instead create a model with desired properties and so declaring an empty object would be:

data: MyType = <MyType>{};

What you are now trying to do is to assign data to your object. For that, use =

ngOnInit() {
  this.data.shareOptions = ['Facebook', 'Twitter', 'Email']
}

As per discussed in comments, you could naturally declare the array inside the Object in the component like so:

data = <MyType>{shareOptions:['Facebook','Twitter','Email']};

Remember though, even with declaring a type, for example interface, it doesn't exist on run time. The typing is just for the compiler to help you and tell you when you are trying to assign values or properties that do not exist in your model. So you can actually override all models and your app will run without error.

But do type your data and avoid using any!

AT82
  • 71,416
  • 24
  • 140
  • 167
  • Thanks for your answer @AJT_82, but should I put `data: Object = {};` and data.shareOptions = ['Facebook', 'Twitter', 'Email']` before the consctructor, in the constructor or somewhere else? – Louis Mar 26 '17 at 18:28
  • and why isn't there any "this"... I thought this was necessary to use variables in the scope. – Louis Mar 26 '17 at 18:35
  • Yes, if you are assigning values e.g in ngOnInit you need to use `this`, just didn't include that in my answer, I'll change that ;) Here's a simple plunker: http://plnkr.co/edit/E1Q1jg3GciA2H3hy85ew?p=preview – AT82 Mar 26 '17 at 18:54
  • But what's the use of having a "constructor" in you have then use another function (ngOnInit) ? – Louis Mar 26 '17 at 19:01
  • You can read about the difference here in these good answers: http://stackoverflow.com/questions/35763730/difference-between-constructor-and-ngoninit :) – AT82 Mar 26 '17 at 19:02
  • You can of course use the constructor, I just personally like to keep everything that is not needed away from the constructor, since I'm coding with angular, then do it the *angular way* :) – AT82 Mar 26 '17 at 19:09
  • Ok I see, is that "best practice" to use ngOnInit to initialize variables ? And why use that, when declaring data:any = {} allows no to use ngOnInit ? – Louis Mar 26 '17 at 19:14
  • Your situation is a bit "special". Actually for example, if your array would be a standalone array, I would just initially declare it `array: string[] = ['Facebook'...]` in the component instead of ngOnInit, but in your case compiler doesn't really like your situation when you do eg `data.name = 'name'` in the component. If you want you can of course declare the array when you declare the object, like: `data: Object = {shareOptions:['Facebook']}` but in this case I personally think it looks cleaner the way I did. This is really actually up to you... – AT82 Mar 26 '17 at 19:21
  • But yes, as a general rule of thumb would be, if you have default values, declare them in the component (outside constructor and ngOnInit). Maybe I should change the answer and actually do `data: Object = {shareOptions:['Facebook....']}` hmm. – AT82 Mar 26 '17 at 19:28
  • Just think it looks cleaner and more readable the way I answered :D – AT82 Mar 26 '17 at 19:28
  • Updated answer a bit related to this discussion... But the main point I think is though that you drop the initialization like `data.techniqueText: string;` That doesn't make sense at all in this case and besides, are you using an IDE?? At least my IDE (Visual Studio Code) complains ruthlessly when I try to declare the object like you have :) – AT82 Mar 26 '17 at 19:39
5

in my experience i created object the following way. but i got errors when i ran build script in angular 5.2. then i used second way.

wrong way:

 data = {};

right way:

 data:any = {};
Kumaresan Perumal
  • 1,926
  • 2
  • 29
  • 35
2

In case there is already a model class created

    let car = <ICar>{};
    car.Name= "Audi";
    car.Model = "A4";
    car.category = "German";
Charlie
  • 4,827
  • 2
  • 31
  • 55
0

First You need to create a new class in your model file. if there isnt any model file create new one. then create an class with properties like below.

Class Data{

 shareoptions: [];
 techniqueText: string;
 frequScaleWording: [];
 fitnessWording: [];
 levelName: [];
}

Then using that class create new object in your component

@Component({
    selector: 'page-weightlevel'
    , templateUrl: 'weightlevel.html'
})
export class WeightlevelPage {

    name: string;
    firstNavParam: boolean;


    constructor(
        public navCtrl: NavController,
     data = new Data();
    data.shareoptions = ['Facebook', 'Twitter', 'Email'];
        ....

PS

After : mark you can assign a data type. ['Facebook', 'Twitter', 'Email'] is not a data type. if you need to assign data an array please use = mark. if you need to assign value to array please do it inside the contructor

 data.shareoptions = ['Facebook', 'Twitter', 'Email'];

Edited:

After : mark you can assign a data type. ['Facebook', 'Twitter', 'Email'] is not a data type. if you need to assign data an array please use = mark. if you need to assign value to array please do it inside the contructor

@Component({
    selector: 'page-weightlevel'
    , templateUrl: 'weightlevel.html'
})
export class WeightlevelPage {

    name: string;
    firstNavParam: boolean;
    data = any;
    data.shareoptions:any;
    data.techniqueText: string;
    data.frequScaleWording: string[];
    data.fitnessWording: string[];
    data.levelName: string[];

    constructor(
        public navCtrl: NavController,
        data.shareoptions= ['Facebook', 'Twitter', 'Email'];
Krishan
  • 2,356
  • 6
  • 36
  • 47
  • I don't understand, some of you put the declarations in the constructor(...) some other put them before and some put them in the constructor(){ ... }. Really I don't get that – Louis Mar 26 '17 at 18:41
  • And I don't want to create a new class, it's just a simple object I need to be flexible and add or remove key:value pairs if I need it. – Louis Mar 26 '17 at 18:42
0

I don't understand the interface solutions, and they've been downrated, so I went with this:

@Component({
    selector: 'page-weightlevel'
    , templateUrl: 'weightlevel.html'
})
export class WeightlevelPage {

name: string;
firstNavParam: boolean;
data = any;
data.shareoptions: ['Facebook', 'Twitter', 'Email'];
data.techniqueText: string;
data.frequScaleWording: string[];
data.fitnessWording: string[];
data.levelName: string[];

constructor(
    public navCtrl: NavController,
    public navParams: NavParams,
    private storageService: LocalStorageService
    , public globalVars: GlobalVars
) {

    this.globalVars.addGlobalVar("isWebIntegration", false);

    this.data.shareoptions = ['Facebook', 'Twitter', 'Email'];

and it seems to work.

Louis
  • 2,548
  • 10
  • 63
  • 120