error setelah migrasi ke null safety

Beranda › Forums › Belajar Flutter Mobile Apps Tingkat Mahir › error setelah migrasi ke null safety

Viewing 15 posts - 1 through 15 (of 29 total)
  • Author
    Posts
  • #51724
    Vram Adel Handrio
    Participant

      Dear coach..

      saat migrasi ke null safety terjadi error pada emulator = Exeption = Error terjadi kesalahan..

      selain itu saya coba tambahkan note baru juga muncul error berikut: RangeError(index):invalid value: Not in inclusive range 0..3:-1

      mohon petunjuknya coach..

      #51725
      Vram Adel Handrio
      Participant

        ini kode add_or_detail_screen coach:

        import ‘dart:ffi’;

        import ‘package:flutter/material.dart’;
        import ‘package:intl/intl.dart’;
        import ‘package:notes/models/note.dart’;
        import ‘package:notes/providers/notes.dart’;
        import ‘package:provider/provider.dart’;

        class AddOrDetailScreen extends StatefulWidget {
        static const routeName = ‘/addOrDetailScreen’;
        @override
        State<AddOrDetailScreen> createState() => _AddOrDetailScreenState();
        }

        class _AddOrDetailScreenState extends State<AddOrDetailScreen> {
        Note _note = Note(
        id: ”,
        title: ”,
        note: ”,
        // updatedAt: null,
        // createdAt: null,
        );

        bool _init = true;
        // tambah parameter untuk penanda sedang loading atau tidak saat simpan note
        bool _isLoading = false;

        final _formKey = GlobalKey<FormState>();

        void submitNote() async {
        // tambahkan validasi (if) karena migrasi ke null
        if (_formKey.currentState != null) {
        _formKey.currentState!.save();
        }
        // set isLoading jadi true
        setState(() {
        _isLoading = true;
        });
        try {
        final now = DateTime.now();
        _note = _note.copyWith(updatedAt: now, createdAt: now);
        final notesProvider = Provider.of<Notes>(context, listen: false);
        if (_note.id == null) {
        await notesProvider.addNote(_note);
        } else {
        await notesProvider.updateNote(_note);
        }
        } catch (e) {
        await showDialog(
        context: context,
        builder: (builder) {
        return AlertDialog(
        title: Text(‘Error’),
        content: Text(e.toString()),
        actions: [
        TextButton(
        onPressed: () => Navigator.of(context).pop(),
        child: Text(‘Tutup’),
        )
        ],
        );
        },
        );
        }
        // notesProvider.addNote(_note);
        Navigator.of(context).pop();
        }

        @override
        void didChangeDependencies() {
        if (_init) {
        String? id = ModalRoute.of(context)!.settings.arguments as String?;
        // tambahkan fungsi if untuk validasi penambahan note baru
        //jika id tidak sama dengan null baru cari note dari provider,
        //jika null berarti note baru dan tidak perlu cari data atau id dalam provider
        if (id != null) {
        _note = Provider.of<Notes>(context).getNote(id);
        }
        _init = false;
        }
        super.didChangeDependencies();
        }

        // fungsi untuk merubah format waktu di detail note
        String _convertDate(DateTime dateTime) {
        int diff = DateTime.now().difference(dateTime).inDays;
        if (diff > 0) return DateFormat(‘dd-MM-yyyy’).format(dateTime);

        return DateFormat(‘hh-mm’).format(dateTime);
        }

        @override
        Widget build(BuildContext context) {
        return Scaffold(
        appBar: AppBar(
        actions: [
        TextButton(
        onPressed: submitNote,
        // tambahkan fungsi isLoading
        child: _isLoading
        ? CircularProgressIndicator()
        : Text(
        ‘Simpan’,
        style: TextStyle(color: Colors.white),
        ),
        )
        ],
        ),
        body: Stack(
        children: [
        Container(
        height: double.infinity,
        padding: EdgeInsets.all(12),
        // wrap dengan SingleChildScrollView agar bisa di scroll
        child: SingleChildScrollView(
        child: Form(
        key: _formKey,
        child: Column(
        children: [
        TextFormField(
        // tambahkan initialValue agar saat note ditekan memunculkan judul
        initialValue: _note.title,
        decoration: InputDecoration(
        hintText: ‘Judul’, border: InputBorder.none),
        onSaved: (value) {
        _note = _note.copyWith(title: value);
        },
        ),
        TextFormField(
        // tambahkan initialValue agar saat note ditekan memunculkan isi note
        initialValue: _note.note,
        decoration: InputDecoration(
        hintText: ‘Tulis Catatan Disini…’,
        border: InputBorder.none),
        onSaved: (value) {
        _note = _note.copyWith(note: value);
        },
        // tambahkan maxLines untuk menampilkan note tulisan ke bawah
        maxLines: null,
        ),
        ],
        )),
        ),
        ),
        // 1. Untuk menampilkan kapan note terakhir diubah
        // 2. wrap dengan Positioned agar update waktu pindah ke bawah
        // 3. tambahkan fungsi if karena ada penambahan note baru sedangkan note.updatedAt masih null
        // 4. jika note.updated tidak null maka baru tampilkan kapan terakhir diubah note nya
        if (_note.updatedAt != null)
        Positioned(
        bottom: 10,
        right: 10,
        child: Text(‘Terakhir diubah ${_convertDate(_note.updatedAt!)}’),
        ),
        ],
        ),
        );
        }
        }

        #51752
        Vram Adel Handrio
        Participant

          Saya coba matikan internet dan hot reload, note yang tersimpan sebelumnya bisa muncul, namun jika internet di hidupkan dan di hot reload lagi kembali terjadi error pada emulator = Exeption = Error terjadi kesalahan..

          Mohon petunjuknya coach..

          #51766
          Anonymous

            Hi, bisa kirimin code lainnya kamu?
            sepertinya notes.dart dan notes_grid.dart

            #51768
            Vram Adel Handrio
            Participant

              notes.dart coach..

              import ‘dart:io’;

              import ‘package:flutter/cupertino.dart’;
              import ‘package:notes/api/note_api.dart’;
              import ‘package:notes/database/database_helper.dart’;
              import ‘package:notes/models/note.dart’;

              class Notes with ChangeNotifier {
              List<Note> _notes = [
              Note(
              id: ‘N1’,
              title: ‘Catatan Materi Flutter’,
              note:
              ‘Flutter merupakan Software Development Kit (SDK) yang bisa membantu developer dalam membuat aplikasi mobile cross platform. Kelas ini akan mempelajari pengembangan aplikasi mobile yang dapat dijalankan baik di IOS maupun di Android’,
              updatedAt: DateTime.parse(‘2021-05-19 20:33:33’),
              createdAt: DateTime.parse(‘2021-05-19 20:33:33’),
              ),
              Note(
              id: ‘N2’,
              title: ‘Target Pembelajaran Flutter’,
              note:
              ‘Peserta dapat mengembangkan aplikasi mobile (IOS dan Android) menggunakan flutter,\nPeserta memahami konsep pengembangan aplikasi menggunakan flutter,\nPeserta dapat menjalankan aplikasi mobile di IOS dan Android ataupun Emulator,\nPeserta memahami bahasa pemrograman Dart,\nPeserta dapat mendevelop aplikasi mobile menggunakan flutter dan dart dari dasar secara berurutan.’,
              updatedAt: DateTime.parse(‘2021-05-20 20:53:33’),
              createdAt: DateTime.parse(‘2021-05-20 20:53:33’),
              ),
              Note(
              id: ‘N3’,
              title: ‘Belajar Flutter di ITBOX’,
              note: ‘Jangan lupa belajar flutter dengan video interactive di ITBOX.’,
              updatedAt: DateTime.parse(‘2021-05-20 21:22:33’),
              createdAt: DateTime.parse(‘2021-05-20 21:22:33’),
              ),
              Note(
              id: ‘N4’,
              title: ‘Resep nasi goreng’,
              note:
              ‘Nasi putih 1 piring\nBawang putih 2 siung, cincang halus\nKecap manis atau kecap asin sesuai selera\nSaus sambal sesuai selera\nSaus tiram sesuai selera\nGaram secukupnya\nKaldu bubuk rasa ayam atau sapi sesuai selera\nDaun bawang 1 batang, cincang halus\nTelur ayam 1 butir\nSosis ayam 1 buah, iris tipis\nMargarin atau minyak goreng 3 sdm.’,
              updatedAt: DateTime.parse(‘2021-05-20 21:51:33’),
              createdAt: DateTime.parse(‘2021-05-20 21:51:33’),
              ),
              ];

              Future<void> getAndSetNotes() async {
              // tambahkan fungsi try & catch untuk mengatasi error
              try {
              _notes = await NoteApi().getAllNote();
              // fungsi untuk gunakan getAllNote ke provider
              await DatabaseHelper().insertAllNote(_notes);
              notifyListeners();
              } on SocketException {
              // tambahkan fungsi agar saat internet tidak tersambung yang ditampilkan adalah data dari database
              _notes = await DatabaseHelper().getAllNote();
              notifyListeners();
              } catch (e) {
              return Future.error(e);
              }
              }

              List<Note> get notes {
              // mengurutkan note ( yang di pin ditampilkan lebih dahulu)
              List<Note> tempListNote = _notes.where((note) => note.isPinned).toList();
              tempListNote.addAll(_notes.where((note) => !note.isPinned).toList());
              return tempListNote;
              }

              // menambahkan toggleIsPinned untuk merubah isPinned yang true ke false dan sebaliknya
              Future<void> toggleIsPinned(String? id) async {
              // menampung atau mencari note dengan id yang sama
              int index = notes.indexWhere((note) => note.id == id);
              try {
              // melakukan validasi
              if (index >= 0) {
              _notes[index].isPinned = !_notes[index].isPinned;
              // ganti tanggal update pada server
              _notes[index] = _notes[index].copyWith(updatedAt: DateTime.now());
              // tambahkan notifier untuk memberi tau widget yang listen ke provider bahwa data sudah berubah
              notifyListeners();
              // panggil fungsi toggleIsPinned pada API sebelum notifyListeners
              await NoteApi().toggleIsPinned(
              id, _notes[index].isPinned, _notes[index].updatedAt!);
              // setelah update toggleIspinned ke API maka akan update toggleIspinned di databaseHelper
              await DatabaseHelper().toogleIspinned(
              id,
              _notes[index].isPinned,
              _notes[index].updatedAt!,
              );
              }
              } catch (e) {
              _notes[index].isPinned = !_notes[index].isPinned;
              notifyListeners();
              return Future.error(e);
              }
              }

              // 1. fungsi addNote untuk menambahkan note ke provider
              Future<void> addNote(Note note) async {
              try {
              // 2. panggil fungsi postNote dan tambahkan await, future dan async
              // 3. tampung return id dari API dengan membuat String id:
              String? id = await NoteApi().postNote(note);
              // 4. sebelum tambahkan notes ke dalam _notes buat note.copyWith(id: id saat kita post)
              note = note.copyWith(id: id);
              // setelah add note ke API maka akan add note di databaseHelper
              await DatabaseHelper().insertNote(note);
              _notes.add(note);
              notifyListeners();
              } catch (e) {
              return Future.error(e);
              }
              }

              Note getNote(String? id) {
              return _notes.firstWhere((note) => note.id == id);
              }

              // Fungsi untuk update
              Future<void> updateNote(Note newNote) async {
              try {
              // sebelum updateNote ke dalam listnote panggil dulu fungsi NoteApi
              await NoteApi().updateNote(newNote);
              // setelah update note ke API maka akan update note di databaseHelper
              await DatabaseHelper().updateNote(newNote);
              int index = _notes.indexWhere((note) => note.id == newNote.id);
              _notes[index] = newNote;
              notifyListeners();
              } catch (e) {
              return Future.error(e);
              }
              }

              // fungsi untuk delete note ketika di swap kiri atau kanan
              Future<void> deleteNote(String? id) async {
              // tambahkan fungsi agar pada saat error apa yang sudah di remove dibalikkan lagi
              int index = _notes.indexWhere((note) => note.id == id);
              Note tempNote = _notes[index];
              try {
              _notes.removeAt(index);
              // _notes.removeWhere((note) => note.id == id);
              notifyListeners();
              // panggil fungsi delete pada note.api
              await NoteApi().deleteNote(id);
              // setelah delete note ke API maka akan delete note di databaseHelper
              await DatabaseHelper().deleteNote(id);
              } catch (e) {
              _notes.insert(index, tempNote);
              notifyListeners();
              return Future.error(e);
              }
              }
              }

              #51769
              Vram Adel Handrio
              Participant

                ini yang notes_grid.dart coach

                import ‘package:flutter/material.dart’;
                import ‘package:notes/models/note.dart’;
                import ‘package:notes/providers/notes.dart’;
                import ‘package:notes/widgets/note_item.dart’;
                import ‘package:provider/provider.dart’;

                class NotesGrid extends StatefulWidget {
                @override
                State<NotesGrid> createState() => _NotesGridState();
                }

                class _NotesGridState extends State<NotesGrid> {
                @override
                Widget build(BuildContext context) {
                // gunakan data provider
                final notesProvider = Provider.of<Notes>(context);
                List<Note> listNote = notesProvider.notes;
                return Padding(
                padding: EdgeInsets.all(12),
                child: GridView.builder(
                itemCount: listNote.length,
                itemBuilder: (ctx, index) => NoteItem(
                id: listNote[index].id,
                ctx: context,
                ),
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2,
                crossAxisSpacing: 8,
                mainAxisSpacing: 8,
                ),
                ),
                );
                }
                }

                #51770
                Anonymous

                  Hi, untuk error messagenya cuma itu aja kah?
                  bisa kasi lebih detail lagi?
                  mngkin seluruh dari error messagenya

                  dan sekalian minta isi code dari note_api.dart ya

                  #51774
                  Vram Adel Handrio
                  Participant

                    g bisa di paste disini coach..saya coba buat post pertanyaan baru coach..

                    #51778
                    Vram Adel Handrio
                    Participant

                      namun saya ada dapat email dari fire base isinya:

                      notes
                      [Firebase] Akses klien ke ‘notes-9f78d-default-rtdb’ Realtime Database Anda akan berakhir dalam 4 hari

                      Anda memilih untuk mulai mengembangkan aplikasi dalam Mode Uji, yang membuat instance Realtime Database Anda sepenuhnya terbuka ke internet. Karena pilihan ini membuat aplikasi Anda rentan terhadap penyerang, aturan keamanan database Anda dikonfigurasi untuk berhenti mengizinkan permintaan setelah 30 hari pertama.
                      Dalam 4 hari, semua permintaan klien ke instance Realtime Database Anda akan ditolak. Sebelum waktu tersebut, harap perbarui aturan keamanan agar aplikasi Anda dapat berfungsi sekaligus melindungi data Anda dengan tepat. Analisis dijalankan setiap hari; jika Anda telah mengubah aturan dalam 24 jam terakhir, perubahan tersebut mungkin tidak diperhitungkan.
                      ATURAN YANG SEGERA BERAKHIR
                      notes
                      Database
                      notes-9f78d-default-rtdb

                      apa pengaruh ya coach ke API code nya?

                      #51779
                      Vram Adel Handrio
                      Participant

                        note.api

                        import ‘dart:convert’;
                        import ‘dart:io’;

                        import ‘package:notes/models/note.dart’;
                        import ‘package:http/http.dart’ as http;

                        // buat class yang berisi semua fungsi untuk koneksi ke server firebase
                        class NoteApi {
                        // buat fungsi untuk mendapatkan seluruh note (list)
                        // tambahkan Future dan async agar fungsi await bisa digunakan
                        Future<List<Note>> getAllNote() async {
                        // print(‘pertama dijalankan’);
                        final uri = Uri.parse(
                        ‘https://notes-9f78d-default-rtdb.asia-southeast1.firebasedatabase.app/notes.json&#8217;);
                        // tambahakan try & catch untuk mengatasi error no internet/SocketException dan merubah tulisannya
                        List<Note> notes = [];
                        try {
                        // tambahkan await agar kode dibawah menunggu proses get data selesai
                        final response = await http.get(uri);

                        print(response.statusCode);
                        if (response.statusCode == 200) {
                        // ubah data json menjadi map
                        final results = json.decode(response.body) as Map<String, dynamic>;
                        // looping map result ke List<Note>
                        results.forEach((key, value) {
                        notes.add(Note(
                        id: key,
                        title: value[‘title’],
                        note: value[‘note’],
                        isPinned: value[‘isPinned’],
                        updatedAt: DateTime.parse(value[‘updated_at’]),
                        createdAt: DateTime.parse(value[‘created_at’])));
                        });
                        } else {
                        throw Exception();
                        }
                        } on SocketException {
                        throw SocketException(‘Tidak dapat tersambung ke internet’);
                        } catch (e) {
                        throw Exception(‘Error terjadi kesalahan’);
                        }

                        return notes;
                        }

                        #51780
                        Vram Adel Handrio
                        Participant

                          // Buat fungsi note API untuk post note baru
                          // tambahkan Future pada string dan async agar fungsi await bisa digunakan
                          Future<String?> postNote(Note note) async {
                          final uri = Uri.parse(
                          ‘https://notes-9f78d-default-rtdb.asia-southeast1.firebasedatabase.app/notes.json&#8217;);
                          // buat map untuk isi/body yang akan dikirim ke server
                          Map<String, dynamic> map = {
                          ‘title’: note.title,
                          ‘note’: note.note,
                          ‘isPinned’: note.isPinned,
                          //1. karena encode akan mengubah data menjadi string json maka note.updatedAt dan note.createdAt di ubah menjadi string dengan toIso8601String
                          //2. tambahkan validasi karena migrasi ke null agar tidak error
                          ‘updated_at’:
                          note.updatedAt == null ? null : note.updatedAt!.toIso8601String(),
                          ‘created_at’:
                          note.createdAt == null ? null : note.createdAt!.toIso8601String()
                          };

                          try {
                          // ubah map jadi string json
                          final body = json.encode(map);
                          // 1. melakukan post
                          // 2. tambahkan await agar kode dibawah menunggu proses get data selesai
                          final response = await http.post(uri, body: body);
                          if (response.statusCode == 200) {
                          return json.decode(response.body)[‘name’];
                          } else {
                          throw Exception();
                          }
                          } on SocketException {
                          throw SocketException(‘Tidak dapat tersambung ke internet’);
                          } catch (e) {
                          throw Exception(‘Error, terjadi kesalahan’);
                          }
                          }

                          #51783
                          Vram Adel Handrio
                          Participant

                            // tambahkan fungsi agar saat note diubah maka akan terupdate juga pada server
                            Future<void> updateNote(Note note) async {
                            final uri = Uri.parse(
                            ‘https://notes-9f78d-default-rtdb.asia-southeast1.firebasedatabase.app/notes/${note.id}.json’);
                            Map<String, dynamic> map = {
                            ‘title’: note.title,
                            ‘note’: note.note,
                            ‘updated_at’: note.updatedAt!.toIso8601String(),
                            };

                            try {
                            final body = json.encode(map);
                            final response = await http.patch(uri, body: body);
                            if (response.statusCode != 200) throw Exception();
                            } on SocketException {
                            throw SocketException(‘Tidak dapat tersambung ke internet’);
                            } catch (e) {
                            throw Exception(‘Error, terjadi kesalahan’);
                            }
                            }

                            #51785
                            Vram Adel Handrio
                            Participant

                              // tambahkan fungsi toggleIspined agar saat note di PIN maka terupdate pada server
                              Future<void> toggleIsPinned(
                              String? id, bool? isPinned, DateTime updatedAt) async {
                              final uri = Uri.parse(
                              ‘https://notes-9f78d-default-rtdb.asia-southeast1.firebasedatabase.app/notes/$id.json&#8217;);
                              Map<String, dynamic> map = {
                              ‘isPinned’: isPinned,
                              ‘updated_at’: updatedAt.toIso8601String(),
                              };
                              try {
                              final body = json.encode(map);
                              final response = await http.patch(uri, body: body);
                              if (response.statusCode != 200) throw Exception();
                              } on SocketException {
                              throw SocketException(‘Tidak dapat tersambung ke internet’);
                              } catch (e) {
                              throw Exception(‘Error, terjadi kesalahan’);
                              }
                              }

                              #51786
                              Vram Adel Handrio
                              Participant

                                // fungsi untuk delete dan ubah atau kirim data tersebut ke server
                                Future<void> deleteNote(String? id) async {
                                final uri = Uri.parse(
                                ‘https://notes-9f78d-default-rtdb.asia-southeast1.firebasedatabase.app/notes/$id.json&#8217;);
                                try {
                                final response = await http.delete(uri);
                                if (response.statusCode != 200) {
                                throw Exception();
                                }
                                } on SocketException {
                                throw SocketException(‘Tidak dapat tersambung ke internet’);
                                } catch (e) {
                                throw Exception(‘Error, terjadi kesalahan’);
                                }
                                }
                                }

                                #51788
                                Anonymous

                                  Hi, untuk email tentang Realtime Database Anda akan berakhir dalam 4 hari. Itu maksutnya rules dari realtime database kamu di set agar hanya menerima request sampai dengan tanggal tertentu saja, karena pas pertama kali buat realtime database, kita memilih untuk mulai membuat database dalam test mode.
                                  makanya kalau kamu lihat rules dari realtime database kamu.
                                  kamu akan melihat code kurang lebih seperti ini

                                  {
                                    "rules": {
                                      ".read": "now < 1660669200000",  // 2022-8-17
                                      ".write": "now < 1660669200000",  // 2022-8-17
                                    }
                                  }

                                  nah untuk mengatasi hal tersebut
                                  kamu bisa ubah “now < 1660669200000” menjadi true saja agar kamu akan selalu ngebolehin untuk akses read dan write ke realtime database tanpa batasan waktu.

                                  jadi nanti rules kamu akan seperti ini.

                                  {
                                    "rules": {
                                      ".read": true,  
                                      ".write": true,  
                                    }
                                  }
                                Viewing 15 posts - 1 through 15 (of 29 total)
                                • You must be logged in to reply to this topic.
                                Shopping cart0
                                There are no products in the cart!
                                Continue shopping