16

I'm using Angular 4 with reactiveforms, momentjs, and primeng calendar I'm tying to use setValue and have tried patchValue on a reactiveForm field which contains a Date. This date has been created via a primeng calendar.

purchaseDate: Sat Sep 02 2017 00:00:00 GMT+0100 (GMT Daylight Time)

I use this 'date' to do a couple of things and then onSumbit of the form I convert the date using momentjs to a clean format ready for the backend to accept (i.e. YYYY.MM.DD) using.moment().format(....

However when I run the .setValue I'm getting the following console error ERROR Missing number at position 0 and can't figure out why.

// convert the date
let newDate = moment(this.form.get('purchaseDate').value).format('YYYY.MM.DD');
// let newDate = moment(this.form.get('purchaseDate')).format('YYYY.MM.DD');
// with or without .value - display the same below (2017.09.01)
console.log(newDate); // 2017.09.01
this.form.get('purchaseDate').setValue(newDate);

// if I create a seperate (empty) reactiveForms field to test against
this.form.get('testField').setValue(newDate) // this works fine

I have traced the issue down to when i try to set / patch the primeng calendar value - for some reason is doesn't like to be changed.

UPDATED monent format

The issue seams to be happening on the setValue now getting the following error Unexpected literal at position 2 at viewWrappedDebugError

fidev
  • 1,222
  • 2
  • 21
  • 51
  • 1
    You will need to pass in the formGroup value and I don't think moment will accept a single **y**. `moment(this.form.get('purchaseDate').value).format('yy.MM.dd');` – JayChase Sep 05 '17 at 09:47
  • Moment [`format`](http://momentjs.com/docs/#/displaying/format/) does not accept lowercase `y` as year token, use `Y`, `YY` or `YYYY` instead. Moreover note that lowercase `dd` token stands for _day of the week_ (`Su` `Mo` ... `Fr` `Sa`), use uppercase `DD` if you want _day of the month_ (`01` `02` ... `30` `31`) – VincenzoC Sep 05 '17 at 10:05
  • @JayChase & @VincenzoC hi, thanks - I've updated the code with your suggestion but now getting `ERROR Error: Unexpected literal at position 2` – fidev Sep 05 '17 at 10:20
  • FYI @JayChase omitting `.value` makes no difference, I'm logging `newDate` out and the same appears with or without `.value` – fidev Sep 05 '17 at 10:30
  • Did you tried to make `newDate` a moment object (`let newDate = moment(this.form.get('purchaseDate').value)`) and then set the value of `purchaseDate` as Javascript Date (using moment [`toDate()`](http://momentjs.com/docs/#/displaying/as-javascript-date/) : `this.form.get('purchaseDate').setValue(newDate.toDate());`)? – VincenzoC Sep 07 '17 at 13:27
  • @VincenzoC Thanks but that just sets the same value as before which is an object `Sat Sep 02 2017 00:00:00 GMT+0100 (GMT Daylight Time) {}` - I want to set a string `2017-09-02` . Hence why I use `.format()` – fidev Sep 07 '17 at 14:08
  • There are couple of notes that you should pay attention to regarding Date type and parsing it. First of all, it depends on how you set the type for `purchaseDate` in the backend model and also in the frontend model. If it is set `type: Date`, it won't be able to take in a `string` value. Again, it depends on what you are going to do with the `purchaseDate` that it requires you to set its type to `Date` (Date functions, custom filtering...). If it is not the case, just set its type to `String` then parse your input from the frontend as you want to. To display, remember there's Pipe. – Chau Tran Sep 11 '17 at 18:32

2 Answers2

14

The thing is that PrimeNG date picker expects to receive instance of Date class as a value and it returns instance of a Date class as value. So that's why your attempts to put object of other types in there failed.

It's not clear why you attempt to call setValue() in the submit handler.

If your goal is to modify value programmatically follow suggestion from VincenzoC in comments - modify object and transform it back to Date object before passing it to setValue().

let newDate: Date = moment(this.form.get('purchaseDate').value).add(5, 'days').toDate();
this.form.get('purchaseDate').setValue(newDate);

If your goal is to format Date object for submitting to backend, you don't need to call setValue() at all. Format Date object to string and pass this string instead of Date object to the backend API. If you submitting whole value object from form you can modify it this way before submitting:

let newDate: string = moment(this.form.get('purchaseDate').value).format('YYYY.MM.DD');
let dataForBackend = { ...this.form.value, purchaseDate: newDate };
this.myBackend.sendData(dataForBackend);
Yaroslav Admin
  • 13,880
  • 6
  • 63
  • 83
1

I had similar problem and I noticed I tried to give PrimeNG date in a wrong order:

{date: "2018-01-31"} - works perfectly fine,
{date: "31-01-2018"} - ERROR Missing number at position 0

Was as easy as that in my case.

hardfi
  • 59
  • 3