Home > OS >  array.push is missing the following properties from type
array.push is missing the following properties from type

Time:12-07

I am having an issue with my register page in IONIC.

Right now I am using a data.json file where all the data is stored, and i want to create another user (member) in here. For creating a member I only need a bit of the users information (name, mail and password) but the user info exists of way more data.

The error I'm getting is that my arrayPush is missing the following properties (the ones that I don't want to add yet and rather leave empty).

This is my TS

import {Component, Input, AfterViewInit, Output, OnInit} from '@angular/core';
import { async } from '@angular/core/testing';
import { Router } from '@angular/router';
import {AlertController, ModalController, NavParams} from '@ionic/angular';
import data from '../../../../data.json'

@Component({
  selector: 'app-register',
  templateUrl: './register.page.html',
  styleUrls: ['./register.page.scss'],
})
export class RegisterPage implements OnInit {
  @Input() fullName = '';
  @Input() email = '';
  @Input() password = '';
  @Input() repeatPassword = '';

  messageString: string;
  today = new Date();

  constructor(private router: Router, private alertController: AlertController) {
  }

  ngOnInit() {}

  onRegister() {
    //Grab data from HTML inputs and check if valid. If not popup.
    if (this.fullName === '') {this.messageString = "You didn't enter a name.";this.errorMessage();return;}
    if (this.email === '') {this.messageString = "You didn't enter an mail address.";this.errorMessage();return;}
    if (this.password === '') {this.messageString = "You didn't enter a password.";this.errorMessage();return;}
    if (this.password != this.repeatPassword) {this.messageString = "The passwords don't match.";this.errorMessage();return;}

    var firstname = this.fullName.split(" ")[0];
    var lastname = this.fullName.split(" ").pop();
    
    //save all data to JSON
    (data).members.push({ 
      fullname: this.fullName,
      firstname: firstname,
      lastname: lastname,
      mail: this.email,
      password: this.password,
    });
    
    //Redirect to homepage.
    this.router.navigateByUrl('/home').then(r => {});
  }
  
  // Alert emails dont match
  async errorMessage() {
    const alert = await this.alertController.create({
      cssClass: 'alerts',
      header: 'ERROR',
      message: this.messageString,
      buttons: [
        {
          text: 'Okay',
          cssClass: 'yes'
        }
      ]
    });
    await alert.present();
  }

}

and this is my data.json

{
  "members": [
    {
      "id": 1,
      "gender": "0",
      "fullname": "X X",
      "firstname": "X",
      "infix": "",
      "lastname": "X",
      "number": "06-12345678",
      "mail": "[email protected]",
      "image": "https://pbs.twimg.com/media/EHMN4bVWoAUXhUz.jpg",
      "password": "admin1",
      "birthdate": "14-07-2001",
      "country": "Netherlands",
      "address": "Testweg 1a",
      "state": "Noord Holland",
      "city": "Amsterdam",
      "zip": "1234BC",
      "subscription": "26 Dec. 2020"
    }
  ]
}

I only want to fill the following JSON objects so far for a new user fullname, firstname, lastname, email, password

CodePudding user response:

Preface: I'm not entirely sure what the overall intention of the code is, but the answer below deals with the type issue you mentioned. But the code shown pushes to a data array that was read, initially, from data.json, and doesn't (in the code shown) seem to save that array anywhere. As JSON Derulo points out, pushing to that array has no effect on the data.json file, just the in-memory array.


It sounds like TypeScript is inferring the type of data from data.json, since you aren't giving a type explicitly. TypeScript won't (can't) infer that a property should be optional. To do that, you have to specify it.

There are several ways you can do that.

  • List all the properties yourself in a type definition.
  • List all the optional properties in a type definition, allowing the other (required) properties to be inferred.
  • List all the required properties in a type definition, allowing the other (optional) properties to be inferred.

Of those, the last one seems most useful to what you describe:

import sampleData from "../../../../data.json";

type MemberType =
    Partial<typeof sampleData["members"][number]>
    & Pick<
        typeof sampleData["members"][number],
        "fullname" | "firstname" | "lastname" | "mail" | "password"
    >;

const data: typeof sampleData & {members: MemberType[]} = sampleData;

Playground link

That lets TypeScript infer the type from data.json, but then we make all properties optional, and then override the ones that should be required with their original non-optional definition.

  • Related