TypeScript error: Type 'void' is not assignable to type Promise<Note[]>

import { Component } from ‘@angular/core’;
import { NavController } from ‘ionic-angular’;
import {AddNotesPage} from “…/add-notes/add-notes”;
import {NoteServices} from “…/…/providers/note-services/note-services”;
import {Note} from “…/…/model/note.model”;
@Component({
selector: ‘page-home’,
templateUrl: ‘home.html’
})
export class HomePage {
notes: Promise<Note[]>;
constructor(public navCtrl: NavController,private noteService:NoteServices) {

}
addNote(){
this.navCtrl.push(AddNotesPage);
}
ionViewWillEnter(){
this.notes = this.getAllnotes();
}
getAllnotes(){
return this.noteService.getAllnotes();
}
}

I have this error and the errors show like TypeScript error: Type ‘void’ is not assignable to type Promise<Note[]> . Could you all help me out on this. Thanks.

ionViewWillEnter(){
this.notes = this.getAllnotes();

  1. I think you’d want to declare notes as: notes: Note[];
  2. What does this.noteService.getAllNotes() return? Some code would be nice.

123

Typescript Error
Type ‘void’ is not assignable to type ‘Note’.
…:/Users/Steven Duong/Desktop/reference code ionic/myNotes/src/pages/home/home.ts
ionViewWillEnter(){
this.notes = this.getAllnotes();
}

I have updated and the error is showing up like these. Thanks.

This.noteService.getAllnotes return an array

  1. Please stop posting images. They’re hard to read.

  2. getAllNotes doesn’t return anything. In order to return anything it has to have return in it, and for your case it then needs to return notes.

1 Like

Could you please advise? I have fixed, but the error is still the same. Thanks.

A repo is also better yes…

  1. As @SigmundFroyd mentioned, your this.noteService.getAllnotes() does not return anything.
  2. The this.storage.get('notes') returns an promise, so you should handle the result of that promise where you can return your data. And then next, you should handle result of the promise in your page (where you assign it to the array in you page)

You need to change getAllNotes to:

getAllnotes(){
  return this.storage.get('notes').then(
    (notes)=>{
      this.notes = notes==null ? [] : notes;
      return this.notes;
    }
  );
}

Then, because it returns a promise you need to attach a .then wherever you consume it.
e.g.

this.noteService.getAllnotes()
.then(notes => this.notes = notes);

There is a fairly subtle yet deadly race condition here, which is why I suggest never using storage for in-app communication, only for persistence across app restarts.

In other words, you should only call storage.get(), directly or indirectly, once, at app startup. If getAllNotes() is to remain part of the public interface of NoteServices, it should not be reading from storage.

The problem is that storage writes themselves are not synchronous, so imagine this situation: a modal dialog triggers a call to saveNote() and then closes itself, which results in a list of notes page calling 'getAllnotes()` to refresh its list of notes. You have no guarantee as to whether or not the freshly saved note will be there. Sometimes it will, sometimes it won’t.

It is theoretically possible to have saveNote() return a future, and to require all clients of NoteServices understand this situation, or to create an internal spinlock inside NoteServices. I have tried a bunch of things along these lines, and have yet to find one that is not both overly complex and still brittle and error-prone.

So I have decided that it is cleanest and safest to use “app exiting and restarting” as the mother of all synchronization points when dealing with storage, which means that the only time an app can read from storage is at startup.