Being new to flutter and dart, I am looking for ways to structure my projects. I have found that the Repository pattern made its way to dart (I have a strong Java background), but I have found that there's not the necessary tools yet to properly implement a repository.
How I would normally approach this is to first create the simple straightforward methods. I ended up with the following dart code:
abstract class CategoryRepository {
Future<List<Category>> getCategories();
Future<Category?> getCategoryById(String id);
}
All is good. But now imagine I have a PostRepository, and I only want to return posts of a specific category? I am missing a standardized way in flutter how to add conditions to my repository select methods. I cannot believe nobody has written something for this purpose before so I am doubting whether I am on the right track here. Maybe my Java background is throwing me off.
In Java (specifically Spring JPA) I am used to specifications, predicates and criteria as documented here.
In .NET you can implement select methods of a repository pattern with the Expression class which allows you to use LINQ to add select criteria as documented here.
For Flutter or Dart, what would be the equivalent? Or am I on the wrong track?
I have found the flutter_repository package, but it is deprecated (without a reason). Looking at the documentation it indeed had Specifications which are used to add conditions. This would be exactly what I expect/need, but again it's deprecated.
This is where I cannot find the information publicly anymore and am questioning "how to properly implement repository in flutter/dart", hence the reason for posting this.
Related
Since dart is an open source language I was trying to get the implementations of dart abstract classes? for example I would like to see how dart team implemented String abstract class to see "trim()" method implementation, there is similar question here maybe but couldn't help me.
Navigating the Dart SDK repository require some experience before it gets easier. One reason is that it contains different implementation of some methods depending on the target platform (native vs JavaScript). Also, sometimes the native implementation is being done in C++ depending on if that makes more sense.
In your case, I have found the following two implementation of String.trim(). The first is used for native (Dart VM and AOT):
https://github.com/dart-lang/sdk/blob/1278bd5adb6a857580f137e47bc521976222f7b9/sdk/lib/_internal/vm/lib/string_patch.dart#L485
And the second is used when the target is JavaScript (sometimes, we can proxy methods directly to native JavaScript methods but in this case, the trim() in JS does have a different behavior from the String.trim() in Dart. This is documented above the method in the link):
https://github.com/dart-lang/sdk/blob/1278bd5adb6a857580f137e47bc521976222f7b9/sdk/lib/_internal/js_runtime/lib/js_string.dart#L263
Note about the annotations used in the first link
The internal Dart source code can often look a bit alien compared to the normal Dart code. E.g.:
#pragma("vm:recognized", "asm-intrinsic")
#pragma("vm:external-name", "String_charAt")
external String operator [](int index);
The #pragma is used tell the Dart compiler some additional information. It can e.g. be to enforce inlining of certain methods. Or as here, tell the compiler it should call a C++ method bound to an entry called String_charAt. If we make a search in the GitHub repo. we can find that method here:
https://github.com/dart-lang/sdk/blob/e995cb5f7cd67d39c1ee4bdbe95c8241db36725f/runtime/lib/string.cc#L443-L449
Looks like Flutter for Web and Flutter for Mobile have to exist as separate projects due to the imports.
Example:
import 'package:flutter_web/material.dart
vs
import 'package:flutter/material.dart';
Is there anyway to build one flutter project with one code base that works for both web and mobile (ios/android)? If not, is this coming?
If so, can you provide an example app?
Would like to just make one code base for the web and mobile and not have to maintain separate projects/code repos.
The OP's question is a bit old and is no longer applicable at the time of posting(7/21/2020). Flutter now has consolidated web into the main flutter package, which prevents us from running into issues with imports like this. flutter_web is no longer a separate package.
However, you may have been able to accomplish this even at the time you posted your question with conditional imports. This answer provides an excellent method of doing this. The following are the essentials of that post:
The core idea is as follows.
Create an abstract class to define the methods you will need to use in general.
Create implementations specific to web and android dependencies which extends this abstract class.
Create a stub which exposes a method to return the instance of this abstract implementation. This is only to keep the dart analysis tool happy.
In the abstract class import this stub file along with the conditional imports specific for mobile and web. Then in its factory constructor return the instance of the specific implementation. This will be handled automatically by conditional import if written correctly.
This method allows for you to do these imports based on platform and applies to all packages that may not support every possible flutter platform(e.g. dart:html, dart:js, dart:js_util, dart:io).
The question may sound funny but I think this should be possible.
What I want is to use a repository that is purely custom but is exposed just like a Repository. This service would have methods to get, save, delete and list objects where the data could be from any arbitrary source.
Looking through the code, I think it should be possible since methods are accessed using CrudMethods and RepositoryInvoker. I belief this requires an implementation of RepositoryFactoryInformation that will be discovered by Repositories. I started experimenting a bit and it looks like a full-blown spring-data-noop module.
Am I on the right track or is there an easier way to accomplish this?
I've ended up writing spring-data-custom to create fully customized spring-data repositories, allowing custom code to be used with spring-data-rest etc.
Enable custom repositories (#EnableCustomRepositories)
Annotate eligible entities (#Custom)
Create a repository (extend CustomRepository<T, ID>)
Add custom behavior:
Let repository extend a new interface with the Custom suffix
Create an implementation of the new interface with the Impl prefix
Add one or more CRUD methods named findOne, save, findAll, delete (see DefaultCrudMethods)
Add query methods annotated with #Query
Export repository using spring-data-rest
(copied from README)
As #wwadge correctly mentioned, spring-data-keyvalue is an alternative. Repositories have to implement KeyValueAdapter, e.g. MapKeyValueAdapter.
The easier way is to use spring-data-keyvalue project which does what you are trying to do.
I am developing an IntelliJ IDEA plugin which has to generate some project-specific classes in the Java/Scala project. I have a superclass and a few traits to extend. How can I list methods, which I need to implement in a class being created?
I mean the same list that will appear in the 'Implement methods' dialog.
In the source code for the IDEA community version, take a look at the com.intellij.codeInsight.daemon.impl.quickfix.ImplementMethodsFix class for an example of doing this. The chooseMethodsToImplement method ultimately calls com.intellij.codeInsight.generation.OverrideImplementUtil
.showOverrideImplementChooser(...) to get the methods. Also take a look at the com.intellij.codeInsight.generation.OverrideImplementExploreUtil class.
I'm learning GWT and have started to get the hang of it. I'm at the point where my code is getting to be a spaghetti mess so I'm going back and factoring reasonable bits of it out as Composites. The first problem I ran into was that my tool support failed to give the new Composite class an initWidget() method. It did include a default constructor.
For the time being, I've simply filled in my overridden initWidget() method with a call to super(initWidget(w)) My project compiles and runs as expected, though I feel as though I must be missing something.
What should I keep in mind when overriding init and what if anything do i need to place in the constructor. Is there anything else that I need to know or does it just boil down to regular old Java after this?
Clarification - It has occurred to me that there are probably different answers to this question depending on whether you intend to release said Composite classes as part of a library or simply part of your stand-alone app. I in particular have no intention at this time of developing externally useful components (mainly because I'm so green in this particular technology.)
Thanks!
I'm not sure if I understand what you are trying to do. But for all the Composite's I've written I've never overridden the initWidget method. Because Composite itself doesn't need to be initialized with a constructor, i.e. no need to call super() my constructors of widgets extending composite look something like:
public mywidget() {
SomePanel p = new SomePanel();
....
initWidget(p);
}
As a best practice, imo, only the widget extending Composite should call it's 'own' initWidget.
"GWT Conference: Best Practices for Building Libraries" gives a couple of tips. You should also look at the source of GWT and at the source of one of the libraries for GWT (like gwt-ext)
[EDIT] I just saw another option: suco. From the description:
A micro library that helps to maintain your GWT client code clean and modular.