Meshkat-Shadik / EveryDay-I-Learn

⚠Warning:⚠ This Repository is only for me. Learning new/amazing things everyday and write down to this. Hope a great note for me.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Date: 9 February, 2022 (Flutter)

Passing BlocProvider inside Navigator

CurrentBloc -> main(BlocProvider(FirstPage)) -> FirstPage() -> NextPage()

In this condition NextPage is not wrapped with BlocProvider, and we pass the currentBlocProvider to the next like this.

Navigator.of(context).push(MaterialPageRoute(
              builder: (_) => BlocProvider.value(
                value: BlocProvider.of<CurrentBloc>(context),
                child: NextPage(props),
              ),
            ));

Date: 10 February, 2022 (Flutter)

Riverpod ref.listen based snackbar

 ref.listen<State>(responseStateNotifierProvider,
        (previous, current) {
      current.maybeWhen(
        success: (d) => ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text(d),
            backgroundColor: d.contains("Can't")?Colors.red:Colors.green,
          ),
        ),
        orElse: () {},
      );

JSON Serialized g.dart list modifying

Actually, for a list returning is not mapped in g.dart file. In case, we have to write list manually.

Previously

 'books': instance.books

Modified

'books': instance.books?.map((e) => e?.toJson())?.toList(),,

Tips: Also look out (Debug) the ENUM value wheather it is returning properly or not.

Date: 11 February, 2022 (Prisma+Node.js)

Grab auto-completion in prisma

To show the auto completion, which is the most helping hand to run with Prisma.

_Just put await before it, and for using await we have to wrap the function with _async__

const getStudentById = async (req, res, next) => {
  try {
    const students = await prisma.student.findUnique({
      where: {
        roll: Number(req.query.roll),
      },
      include: { teacher: true },
    });
    res.status(200).json(students);
  } catch (error) {
    next(error);
  }
};

Date: 12 February, 2022 (Flutter + GraphQL)

GraphQL + Flutter CRUD

Source: https://github.com/Mahmudul-Sumoon/GraphQL-Riverpod by Me and @Mahmudul-Sumoon

Problem we have faced, we can't be able to watch updated value in read after mutating datas.

Previously

  @override
  Future<BooksModel> getAllBooks() async {
    QueryResult result = await _client.value.query(
      QueryOptions(
        document: gql(GetData.getAllBooks),
      ),
    );
    if (result.hasException) {
      return BooksModel.fromJson(result.data!);
    } else {
      return BooksModel.fromJson(result.data!);
    }
  }

Updated

  @override
  Future<BooksModel> getAllBooks() async {
    QueryResult result = await _client.value.query(
      WatchQueryOptions(
        document: gql(GetData.getAllBooks),
      ),
    );
    if (result.hasException) {
      return BooksModel.fromJson(result.data!);
    } else {
      return BooksModel.fromJson(result.data!);
    }
  }

Date: 13 February, 2022 (Flutter)

Injectable with Flutter

Some rules,

  • @module - dependency
  • @lazySingleton - dependency
  • @LazySingleton(as: IAuthFacade) - repository/facade
  • @injectable - bloc(application)

Date: 14 February, 2022 (Flutter)

Dartz OptionOf() and some() difference

some

 emit(state.copyWith(
        isSubmitting: false,
        authFailureOrSuccessOption:
            some(failureOrSuccess),
      ));

OptionOf

some(x == null? none():some(x));

//instead of we can write
optionOf(x) //automates the null checking operation

Date: 15 February, 2022 (Flutter Stream)

Stream & StreamSubscription

Stream subscription bloc uses event instead of returning state.

Then we have to watch/fire the event

implementation on bloc (Application Layer)

    on<EventName>((event, emit) async {
      await _noteStreamSubscription?.cancel();
      emit(const State.loading());
      _noteStreamSubscription =
          repo.watchAll().listen((eitherValue) {
        return add(Event.successEvent(eitherValue));
      });
    });

Calling the event coming from stream

    on<SuccessEvent>((event, emit) async {
      emit(event.eitherValue.fold(
        (l) => State.loadFailure(l),
        (r) => State.loadSucess(r),
      ));
    });

implementation on repository (Infrastructure Layer)

Stream<Either<NoteFailure, KtList<Note>>> watchAll() async* {
    final userDoc = await _firestore.userDocument();
    yield* userDoc.noteCollection
        .orderBy('serverTimeStamp', descending: true)
        .snapshots()
        .map(
          (snapshot) => right<NoteFailure, KtList<Note>>(
            snapshot.docs.map((doc) {
              return NoteDto.fromFirestore(doc).toDomain();
            }).toImmutableList(),
          ),
        )
        .onErrorReturnWith((e, stackTrace) {
      if (e is FirebaseException && e.message!.contains('permission-denied')) {
        return left(const NoteFailure.insufficientPermission());
      } else {
        return left(const NoteFailure.unexpected());
      }
    });
  }

Date: 25 February, 2022 (Flutter Stream)

BlocBuilder, BlocListener & BlocConsumer

  • BlocConsumer : Consists of BlocBuilder and BlocListener
BlocConsumer<ConnectivityCubit, bool>(
      listener: (context, state) {
        state
            ? context.router.replace(const SplashPageRoute())
            : const Text("Doesn't show this");
      },
      //shows this Scaffold
      builder: (context, state) => const Scaffold(
        body: Center(
          child: InternetDisablePage(),
        ),
      ),
    );
  • BlocBuilder : Altime listens and builds the widget
BlocBuilder<ConnectivityCubit, bool>(
          builder: (context, state) {
            return state? NormalPage():InternetDisablePage();
          }
);
  • BlocListener : Listens and fire events not build the widget
BlocListener<AuthBloc, AuthState>(
      listener: (context, state) {
        state.map(
          initial: (_) {},
          authenticated: (_) {
            context.router.replace(const NotesOverviewPageRoute());
          },
          unAuthenticated: (_) =>
              context.router.replace(const SignInPageRoute()),
        );
      },

Date: 4 March, 2022 (Flutter Internationalization/Localization)

Usage of Easy Localization

  • Dependency adding to pubspec.yaml
dependencies:
  easy_localization: ^3.0.0
  • Create folder in project like this structure
assets
└── translations
    ├── en.json
    └── bn.json
  • Add the assests to the pubspec.yaml
flutter:
  assets:
    - assets/translations/

work like the picture below. image

  • Add some code in main.dart
  WidgetsFlutterBinding.ensureInitialized();
  await EasyLocalization.ensureInitialized();
  runApp(
    EasyLocalization(
        path: 'assets/translations',
        supportedLocales: const [
          Locale('en'),
          Locale('bn'),
        ],
        fallbackLocale: const Locale('en'),
        child: const MyApp()),
  );
  • Add some more code to MaterialApp
 return MaterialApp(
      localizationsDelegates: context.localizationDelegates,
      supportedLocales: context.supportedLocales,
      locale: context.locale,
      home: const MyHomePage(),
    );
  • Generator
flutter pub run easy_localization:generate -h

flutter pub run easy_localization:generate -S "assets/translations" -O "lib/translations"

flutter pub run easy_localization:generate -S "assets/translations" -O "lib/translations" -o "locale_keys.g.dart" -f keys
  • Add Generated CodegenLoader() inside RunApp's EasyLocalization
assetLoader: const CodegenLoader(),
  • Use in presentation
import 'package:easy_localization/easy_localization.dart'; //for use tr()
 LocaleKeys.yourKeyName.tr(),
  • Change the Locale
context.setLocale(const Locale('en'));

Date: 10 March, 2022 (Flutter - Bottom Bar )

We want to make this type of UI

image

You can use different ways to implement this UI.

_Previously I used Stack_

  • Easy implementation with Expanded.
 Column(
          children: <Widget>[
            Expanded(
              child: ListView(),
            ),
            Container(
              height: 50,
              width: MediaQuery.of(context).size.width,
              color: Colors.blue,
            ),
          ],
        ),

Date: 17 March, 2022 (Dart - Immutability)

Source

https://medium.flutterdevs.com/explore-immutable-data-structures-in-dart-flutter-86c350b7d014#:~:text=In%20object%2Doriented%20and%20functional,adjusted%20after%20it%20is%20made.

In DDD

We should use @immutable at the domain/core/value_objects as this should not be changeable.

Date: 27 May. 2022 (Node.js - Axios multiple request)

const axios = require("axios");

const requestAPI = async (req, res, next) => {
  console.log("request API Called");
  const names = req.query.name.split(",");
  req.names = names;
  next();
};

const requestOne = async (req, res) => {
  console.log("Req ashtese = " + req.names);

  let reqArr = [];

  for (let i = 0; i < req.names.length; i++) {
    reqArr.push(
      axios.get("https://jsonplaceholder.typicode.com/posts/" + req.names[i])
    );
    // console.log(req.names[i]);
  }

  for (let i = 0; i < reqArr.length; i++) {
    //console.log(reqArr[i]);
  }

  axios
    .all(reqArr.map((e) => e))
    .then(
      axios.spread((...responses) => {
        const responseOne = responses[0];
        const responseTwo = responses[1];
        const responesThree = responses[2];
        // use/access the result
        console.log(responseOne.data);
        console.log(responseTwo.data);
      })
    )
    .catch((errors) => {
      // react on errors.
    });
};

Date: 17 June, 2022 (Stack Clipped Area OnTap)

Problem and Solution

https://stackoverflow.com/questions/70928944/flutter-stack-clip-not-detecting-gestures

Stack(
      clipBehavior: Clip.none,
      children: [
        //first child wrapping with column
        Column(
          children: [
            Container(),
          ],
        ),
        //adding a sizedbox
        SizedBox(height: 180),

        //add the clipped area
        Positioned(
          top: 90.0,
          left: size.width / 2.75,
          child: InkWell(
            splashColor: Colors.red,
            onTap: () {
              print('Yes clicked');
            },
            child:Container(
                height: 90,
                width: 90,
                decoration: const BoxDecoration(
                  image: DecorationImage(
                    image:AssetImage('assets/custom_button.png'),
                ),
              ),
            ),
          ),
        ),
      ],
    ),

Date: 17 June, 2022 (Json Parsing Modifying, Flutter)

add jsonKey inside the field. and inside name parameter define your custom type.

@JsonKey(name: 'last_name')
  String lastName;

Date: 22 August, 2022 (enum, Flutter)

Declaring a class for mocking data need to instantiate the class with values. Like,

class Player{
  final String name, position;
  const Player({required this.name, required this.position});
  }
  
  //To use this we have to write like this,
  Player(name:'Messi',position:'RW'),
  Player(name:'Ronaldo',position:'CF');

Instead of this, we can instantiate values in the enum.

enum Player{    
  messi(name:'Messi',position:'RW'),
  ronaldo(name:'Ronaldo',position:'CF');
  
  
  final String name;
  final String position;
  
  const Player({required this.name, required this.position});
}
void main(){
  print(Player.values.map((e)=>(e.name)));
}

Date: 27 September, 2022 (ValueNotifier and ValueListenableBuilder, Flutter)

I was worried about how the ValueNotifier is working without StatefullWidget, this is what I can found!

fun-fact: this is too much hectic to me, I always prefer flutter_hooks in this condition

class MyHomePage extends StatelessWidget {
  MyHomePage({super.key});
  final ValueNotifier<int> _counter = ValueNotifier<int>(0);    //this is instantiation of a int value
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ValueListenableBuilder(                         // this is the builder that is responsible for changing the UI 
            valueListenable: _counter,
            builder: (context, value, _) {                 
              return Text('Count is $value');               
            }),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _counter.value++;                                   // this is how we can modify the value
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

Date: 03 January, 2023 (Pagination, Flutter)

Pagination like this!

page_properties.dart

class PageProps {
  int currentPage;
  int totalPages;
  PageProps({
    required this.currentPage,
    required this.totalPages,
  });

  factory PageProps.initial() => PageProps(currentPage: 0, totalPages: 0);

  @override
  String toString() =>
      'PageProps(currentPage: $currentPage, totalPages: $totalPages)';

  PageProps copyWith({
    int? currentPage,
    int? totalPages,
  }) {
    return PageProps(
      currentPage: currentPage ?? this.currentPage,
      totalPages: totalPages ?? this.totalPages,
    );
  }
}

pagination_bloc.dart

For simplicity I use rxDart here to explain the paginating functionality

class PaginationBloc{
//declaration
late BehaviorSubject<PageProps> _pageProps;
late BehaviorSubject<List<Datum>> _allData;
late BehaviorSubject<List<Datum>> _dataToDisplay;
int _pageItemLimit = 5;

//getters
Stream<List<Datum>> get getAllData => _dataToDisplay.stream;
bool get canIncreasePage => _pageProps.stream.value.currentPage < _pageProps.stream.value.totalPages;
bool get canDecreasePage => _pageProps.stream.value.currentPage > 0;

void init(){
  _pageProps = BehaviorSubject<PageProps>.seeded(PageProps.initial());
  _allData = BehaviorSubject<List<Datum>>();
  _dataToDisplay = BehaviorSubject<List<Datum>>();
}


//bloc
void getData()async{
  //reset the page props
    _pageProps.sink.add(PageProps.initial());
    final data = await _repo.getData(props);
    if(data.length>0)
    {
      _allData.sink.add(data);
      _updateDataToDisplay();
      
      //add the total page size to _pageProps
        _pageProps.sink.add(
          _pageProps.stream.value.copyWith(
            totalPages: (data.length / _pageItemLimit).ceil() - 1,
          ),
        );
    }
}
 //helper for pagination
  _updateDataToDisplay() {
    int visitedItems = _pageProps.stream.value.currentPage * _pageItemLimit;
    int totalItems = _allData.stream.value.length;
    int currentPage = _pageProps.stream.value.currentPage;

    //check overflow condition for _pageItemLimit
    if (totalItems - visitedItems < 5) {
      _pageItemLimit = totalItems - visitedItems;
    } else {
      _pageItemLimit = 5;
    }

    //checking if overflow condition is false
    if (visitedItems < totalItems) {
      _dataToDisplay.sink.add(
        _allData.stream.value.sublist(
          (currentPage * 5),
          (currentPage * 5) + _pageItemLimit,
        ),
      );
    }
  }
  
   increaseCurrentPage() {
    var currentPage = _pageProps.stream.value.currentPage;
    var totalPages = _pageProps.stream.value.totalPages;
    if (currentPage < totalPages) {
      _pageProps.sink
          .add(_pageProps.stream.value.copyWith(currentPage: currentPage + 1));
      _updateDataToDisplay();
    }
  }

  decreaseCurrentPage() {
    var currentPage = _pageProps.stream.value.currentPage;
    if (currentPage > 0) {
      _pageProps.sink
          .add(_pageProps.stream.value.copyWith(currentPage: currentPage - 1));
      _updateDataToDisplay();
    }
  }
  
  //jump to page
  changeCurrentPage(int page) {
    page = page - 1; //because page(UI) starts from 1, but index starts from 0
    var totalPages = _pageProps.stream.value.totalPages;
    if (page >= 0 && page <= totalPages) {
      _pageProps.sink.add(_pageProps.stream.value.copyWith(currentPage: page));
      searchFieldController.clear();
      _updateDataToDisplay();
    }
  }
  
  void dispose(){
  _pageProps.close();
  _allData.close();
  _dataToDisplay.close();
  }

}

Then in the UI we have to listen the getAllData and do the stuffs.

Date: 14 January, 2023 (Unit Testing, FLutter)

A simple tweak for http unit test, though I don't think it's a good way!

setUpAll(()=> HttpOverrides.global = null);

About

⚠Warning:⚠ This Repository is only for me. Learning new/amazing things everyday and write down to this. Hope a great note for me.