Bloc Pattern: Every screen gets its own bloc? - flutter

I am learning the bloc pattern for Flutter and there seems to be a recurring piece of advice that "every screen should have its own bloc".
But what if you queried your server for data that will be used in more than one screen? It seems redundant, and even wasteful, to hit the server several times for the same piece of data, especially if you know that data has not changed (for example, when no operations that mutate/update it have been used).
Is there anyway you can hold that data somehow to reuse it? Is it a good idea to store data used this way at the repository level? Or is this just an accepted cost of using blocs?

Architecture decisions are always highly opinionated and there is no silver bullet.
Well, here you go.
Is there anyway you can hold that data somehow to reuse it?
Offcource yes. You can architect your app like the following way.
Widgets -> Bloc -> Repository -> Local database/ Remote API
So, your bloc will never make any API call directly, but your repo layer will do. Hence, repo layer can decide whether to fetch the data from remote API or local DB or even from the in memory cache. That way, you can reuse the already cached data on multiple screens of your app.
The interesting part is that, unit testing your code will be super easy if you architect your app like this way.
Is it a good idea to store data used this way at the repository level?
Yes.

Related

What is an efficient way of keeping some state data when the page is reloaded in flutter web?

I'm kinda new to flutter web and I wanted to know what is a good, clean way of handling this problem. So consider I have a shop app and the customer has added some products to their cart, this data is saved in my state (I use Riverpod but I reckon it doesn't mater what state management is used). When the user reloads the page, the cart will be empty as expected (since all the states will be reloaded). I wanted to know what is a good way of handling this problem? Should I use cookies, shared preferences, hive, or something else? I just wanted to know what a more experienced developer would recommend. Thank you in advance for any help you provide.
Cookies are usually created by the server, while SharedPreferences is something client specific.
From an architecture point of view, you probably want the server to know about shopping carts (e.g. when the user logs in on a different device; to indicate that product might be sold soon; ... ). This however adds one more layer of complexity and I would only recommend this if you have a good reason for the server to know about it.
The simple straightforward path I would take for a private project is to save it in SharedPreferences. You can write a toJson and a fromJson function and save/load your cart as stringified JSON.
You can later still decide to move that logic to the server over the course of your application if there turns out to be a business need for it.

Flutter Future Provider and Sqflite (the right usage)

As a beginner I need an architectural advice for following scenario.
My application writes a tiny amount of data and return a tiny query result to the user interface (from sqflite) for each user interaction (click).
There can be at least three ways to do so;
Future Provider (Most appropriate way as I see)
ChangeNotifierProvider & Future Builder
Using Flutter List and do all db operations in the background with using future-then functions.
I couldn't succeed on Future Provider and couldn't find a similar example. (almost all future provider examples are related with web services not sqflite)
Because of this I started asking which way is right or can be another way? Future Provider can be the most appropriate way if you say, I will focus on this.
Thank you very much in advance.
Best regards.
If you want to return query based on the user input, you need to go with the second option, i have personally developed a production level app using this strategy and it works like charm.
Here's the link to my github repository for that app, if you feel any difficulty in implementation you may ask.
Code that contains `ChangeNotifierProvider' for DateTime
https://github.com/asadamatic/Daily-Todo/blob/master/lib/main.dart
Code that contains Consumer for ChangeNotifierProvider for DateTime
https://github.com/asadamatic/Daily-Todo/blob/master/lib/Screens/HomeScreen.dart
You nay want to check out the app and see if you can relate to it,
https://play.google.com/store/apps/details?id=com.legacyllc.dailytodo

What to use ? Bloc or Moor in Flutter

So, I am trying to create a project where I am supposed to Call Web API and store the data in my local storage. Which should still have even if the app is killed and then re-opened.
FYI, data will be large and I will require a significant amount of space in the mobile device.
i will be using firebase for login, the payment transaction and etc.
this is my first answer, I hope to help you.
BloC & Moor are not synonyms, BloC is a reactive state management solution that allows you to better manage the interaction between logic and widgets in a reactive way. Moor is a layer between sqlite and your application, it allows you to deal with sqlite using dart code by reacting to database changes through Streams and Futures
I think you do not need to choose one of the two, if your application is going to handle large amounts of data and will grow exponentially I recommend that you implement both as they complement each other, by designing a SOLID structure.

Is Entity Framework also persistance layer?

OK. I know that Entity Framework is ORM. We use it for mapping data from database to object model, and from objects to relational data. But where it fits in a context of persistance layer? Can we say that persistance layer is also Entity Framework?
I would say - No! There are a lot of articles about this topic. But in general you don't want your object-relational mapper to be data-persistent. In fact exactly the opposite, keeping it persistent ignorant you can benefit by using your data classes with different types of data providers such as relational databases, web services, XML files and what not.
To keep data persistence you may take advantage of different design patterns like Repository pattern and Unit Of Work so you can really decouple you business layer from your data layer.
Ok, to make myself clear since it's very difficult through comments, here's an update to what I wanted to explain. Please have in mind that this is just my interpretation, and the way I'm using EF, I've been using it in different projects (desktop and web) but it's not universal, but still covers a lot of the most common scenarios.
So since I'm a big fan of Code First I'll write from this prespective. The Database Model is where your entities lies. Later on based on those entities the EF will generate your database. So what is important on this stage of development - you want to have you database normalized and you want all navigation properties set correctly. Not so trivial tasks as it may seems but that it's, you just care about how efficient your database will be.
Now comes the tricky moment somehow you should deliver you data to the business layer and it's true - as far as we are talking only about data from a database using repository is very arguable. However even then the one advantage that you get when having this Repository between the data and the business logic is that you don't have to take in mind the business needs while creating the data model, and after that this doesn't make it any harder to use your data from inside the business layer even though what exactly will your front end looks like at the time you create the database model.
So at this point let's consider again the example case where in you Database Model you have those two entities - Customers and Orders. When a user log in into your application and wants to see his orders you need to join two tables in order to provide the front end the information that it needs. Option 1 - you don't have a Repository and you are using the DbContext directly from the method that returns the data. That means two things - you gonna have to write the same code everywhere you need to get this specific piece of information and 2 - if the business requirements change and in the same view that since now was used to show a customer and his orders now you have to show some additional info which is taken, let's say from a third table, then what happens - you have to go to each place where you use this view and change the way you retrieve the data. And option 2 - you have Repository, all your methods for accessing data are stored there and the Business Layer is completely ignorant about the way it get's the data, the Database Model is also ignorant about the needs of the business model which lead to loose coupling and only one place where you gonna have to make changes if you have to. In the scenario above, if you indeed use Repository and in your repository you have method called GetUserOrders() and inside this method you make the database call, the joins and so on, and all that the Business layer needs to do to get the data in the proper way is call this method when the requirements change and you have to include one more table, this time you don't have to look for all the places where you are using this data, you just have to modify one method and that's all.
It's pretty much the same logic on the way back. When you have some complex data returned from your front end and you want to save/update the old data with the new one, again - you can do it from the business layer but it leads to the same problem as when you have to get data, instead - you just pass the complex data to another Repository method which knows how to deal with it (say maybe some of the data should be saved directly into database and other should be used to feed a web service or whatever scenario comes to your mind) and here again - when something change, like - you want to use more heavily web services or the opposite, you want to migrate to more database centric design, all you have to do is change the method that takes care about the data the is concerned with this changes and nothing more.
So even though when I'm writing this I can see that DbContext can very well act as a repository and in this regard also as a data persistent layer, there are still some valid reason to not let this happen. Especially right now when the web services are more and more popular, WebAPI2 is out and RESTFull services are frequently used I think that leaving the EF as persistent ignorant as possible is the way to go.
But yet again, this is my opinion. There are a lot of articles on this topic so I urge you to google and read about it, since I think this is very important part form the architecture of every application.
P.S
In response to your comment which was written while I was writing my edited answer:
If I change data source I need to make changes in DAL anyway or in my example in repostitory. - the answer is yes. But there is no way tho change the data source without changing the DAL. The question is how easy will be to do that. I think the with what I've written already you can decide for yourself which way is better but just because I really think this is one of the few really strong arguments of leaving the EF persistent ignorant all write it again. When you have Repository and there are methods which take care for data manipulation, every time something related with the way the data is fetched affects only those methods and nothing else. If you use the context freely, in your business layer even a little change may cause you a lot of trouble just because it always possible to miss something, you have to go through the entire code to make sure that you have fixed all places and it's just not as efficient as having all in one place.

How to create a persistant iphone cache

So I have been doing lots of reading and found out NSCache is not persistent which is a slight problem for what I need to do. I have heard that I will need to use Core data instead... but I don't have any experience with core data so am wondering if its the only solution for persistent data.
The app will allow the user to search through a catalog, by typing in a search parameter in the code and select a distributor for their search parameter. What I want to do when the app loads is download the list of distributors and save them to a "cache" the will be persistent (till when the header I will make at some point changes and demands the app to update the cache), so that if the user turns the app of or the phone next time then open it the manufacture.
Now that I'm getting abit deeper into my app I'm getting abit lost in things for instance how would setting up a cache work with regards to NSURLConnection.
Any suggestions or code examples would be greatly appreciated..
This previous answer of mine might help you decide.
To sum it up:
If your data is small, static and low-complexity, use a collection class and write it to disk using the built-in class methods
If the data is static, low-complexity but large, SQL may be a good solution especially if you already know it.
If the data is dynamic and complex regardless of size, then Core Data is your best choice.
Viewed purely from the technical perspective, Core Data is always the best choice for iOS/MacOS API apps. Core Data is not just a persistence API, it is an API for creating the model layer of the Model-View-Controller design paradigm that the Apple API uses. It not only persist the data, but models it, validates its and provides an easy interface to the rest of the API.
If your going to be writing iOS apps, you need to eventually learn Core Data. However, it does have a learning curve and you should pick the method right now that will let you ship a usable app.
You can also check out sqlite. Here's another question that discusses getting started with sqlite on the phone: Where's the best SQLite 3 tutorial for iPhone-SDK?
The advantage to sqlite is that it is fairly easy to pick up. The downside is that you have to write queries for everything, and that can be a pain. It doesn't save objects, just data, numbers or text.