[{"content":"After months of evening commits, ldash 1.0.0 is out.\nldash is a terminal dashboard for hledger. It turns my plain-text journal into a live overview of net worth, monthly spending, budgets, savings goals, and crypto portfolio — all keyboard-driven, all offline, no browser tab required.\nIf you live in the terminal and use hledger (or want to), this post is for you. New to the world of Plain Text Accounting? It is a small, friendly community built around the idea that your financial data should be a text file you fully own — and ldash is one window into that idea.\nRepo: codeberg.org/md-weber/ldash\nWhy I built ldash I track my finances in plain text with hledger. It is precise, scriptable, and mine forever. (If you are new to the space, hledger sits next to ledger-cli and Beancount as one of the three mainstream plain-text accounting tools — ldash is built specifically for hledger.) But hledger is a CLI: every question (How much did I spend on groceries last month? What is my net worth trend? How is my crypto portfolio doing?) is a separate command with a separate set of flags.\nFor a long time I bounced between three patterns:\na wall of hledger bal/hledger reg commands I had memorized a half-broken bash script that stitched several reports together shelling out to a web tool that needed exporting and uploading data I would rather keep on disk None of it felt right. I wanted one place that answered the four questions I actually ask every week:\nWhat is my net worth, and where is it trending? How much did I spend this month, by category, vs my budget? How is my crypto allocation performing — invested vs price gain vs staking? Am I making progress on my savings goals? ldash is the answer I built for myself.\nWhat you get in 1.0.0 ldash launches into three tabs you can switch with 1, 2, 3 (or Tab):\nPortfolio Holdings table with price, value, allocation %, and per-coin P/L Split between invested, price gain, and staking rewards, so you actually know where the gains came from Stacked or unstacked chart mode (s to toggle) Net worth history with selectable ranges: YTD / 1Y / 2Y / 5Y / All Accounts All asset accounts with EUR valuations and visual bar indicators Drill into any account to see its recent transactions (Enter) Savings goals with progress bars and target amounts Monthly Income and expenses bar chart with per-category breakdown Savings rate gauge Year-over-year comparison Budget tracking inline: progress bars per category, warnings when over budget Drill-down into any expense category A few things that are easy to miss but matter every day:\nBackground refresh — data loads in parallel, the UI never blocks Auto-reload — ldash watches your journal file and refreshes when it changes Lazy tab loading — only the active tab loads on first visit, so startup is instant Hot-reload config — change a color or budget, save the file, see it immediately Tech under the hood Rust + Ratatui for the TUI (if you live in this corner, Awesome Ratatui is a great rabbit hole) hledger as the source of truth — ldash reads from your journal, never writes to it A separate prices.journal file holds crypto price history, so the portfolio view works fully offline CI on Codeberg builds release binaries for x86_64/aarch64 Linux and macOS Tested with unit, snapshot, and integration suites The whole thing is a single binary, ~3 MB, with no daemon and no database. Your data lives in your journal. ldash is just the lens you look through.\nTry it You need Rust 1.70+ and hledger installed. If hledger is brand new to you, the official docs are the single best starting point.\nsh 1 2 3 git clone https://codeberg.org/md-weber/ldash.git cd ldash cargo install --path . Then point it at a journal:\nsh 1 2 3 4 5 ldash /path/to/all.journal # or export LEDGER_FILE=/path/to/all.journal ldash If you keep an all.journal in your finance directory, you can also just cd there and run ldash with no arguments.\nAUR packaging and a Nix flake are in the repo. A Homebrew tap is planned for a 1.0.x patch release.\nConfiguration that stays out of your way On first launch, ldash creates ~/.config/ldash/config.toml with everything commented out. Sensible defaults take over until you decide otherwise.\nYou can:\nSet a default tab, refresh interval, and number format (eu / us) Define monthly budgets per expense category Define savings goals mapped to account prefixes Reassign category colors so your spending chart matches how your brain groups things Pick a theme — or paint your own (see below) Saving the config triggers a hot-reload — no restart.\nThemes: three presets, fully customizable ldash ships with three built-in themes:\ndark — the default. Dark background with a cyan accent. light — light background with a blue accent. Self-contained, so it works on any terminal. solarized — the classic Solarized Dark palette. Dark — default Light — works on any terminal Classic Solarized Dark Pick one in config.toml:\ntoml 1 2 [theme] preset = \"solarized\" # or \"dark\" (default) or \"light\" Every color can also be overridden individually, with or without a preset. Want Solarized but with an orange accent? Mix and match:\ntoml 1 2 3 [theme] preset = \"solarized\" accent = \"#ff8800\" # override just the accent color Available color fields (defaults shown for the dark preset):\nField Default Role accent cyan Borders, highlights, selected tab positive green Income, gains, positive amounts negative red Expenses, losses, negative amounts muted darkgray Secondary text, axis labels gold yellow Net worth line, titles, P/L totals fg white Primary text background #14141e Title bar, popup backgrounds Color values accept named colors (red, green, blue, yellow, cyan, magenta, white, gray, darkgray) or hex codes (#RRGGBB). Theme changes hot-reload the moment you save the file — no restart needed.\nExample config Here is a real-world ~/.config/ldash/config.toml that uses most of what ldash offers:\ntoml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 # Path to hledger journal (overrides $LEDGER_FILE and CLI arg) journal = \"/home/max/Finance/all.journal\" # Auto-refresh interval in seconds refresh_interval = 300 # Default tab on startup: \"portfolio\", \"accounts\", \"monthly\" default_tab = \"portfolio\" # Number format: \"eu\" (1.000,00) or \"us\" (1,000.00) number_format = \"eu\" currency_symbol = \"€\" # Portfolio chart mode: \"stacked\" or \"unstacked\" chart_mode = \"stacked\" # Theme — solarized base, custom accent [theme] preset = \"solarized\" accent = \"#ff8800\" gold = \"#f5c518\" # Per-category expense colors [colors.expenses] Wohnen = \"blue\" Essen = \"yellow\" Transport = \"#B48CFF\" # Monthly budgets per expense category [budgets] \"expenses:Essen\" = 400.0 \"expenses:Freizeit\" = 200.0 \"expenses:Transport\" = 150.0 # Savings goals (target amount + account prefix) [[goals]] name = \"Emergency Fund\" target = 15000.0 account = \"assets:bank:savings\" [[goals]] name = \"New Laptop\" target = 2500.0 account = \"assets:bank:savings:laptop\" Drop in only the parts you care about — every section is optional and defaults fill the rest. A few annotated configs also live in the examples/ directory of the repo.\nWhat 1.0.0 means to me Solo development is a lot of small, invisible decisions. Naming a flag. Choosing a default. Deciding the tenth time whether a feature belongs in 1.0 or in 1.1.\nFor me, 1.0.0 means three things:\nThe core experience is real: I use ldash daily for my own finances. The foundation is stable: tests, CI, release pipelines, packaging. The scope is honest: it does what it claims, nothing more, nothing fake. Shipping 1.0.0 alone is a strange feeling. It is exciting, slightly anticlimactic, and motivating all at once. Now the interesting part starts: real users, real edge cases, real feedback.\nWhat is next The roadmap I am most excited about:\nHomebrew tap (brew install ldash) More chart types and time ranges Smarter portfolio insights (rebalancing hints, cost basis views) Better keyboard onboarding for first-time hledger users Quality-of-life improvements driven by what people actually report If you try ldash and something is missing, broken, or just feels off, please open an issue on Codeberg. The full CHANGELOG.md lives in the repo if you want to track what is shipping. Issues from real users shape the roadmap more than anything I can plan in advance.\nFinal note I built ldash because I wanted a calmer way to look at my own money. Plain-text accounting gives you control. ldash gives you a window into it that does not get in your way.\nIf you are an hledger user — or you have been tempted to try plain-text accounting and were missing the dashboard piece — I would love to hear what you think.\nI write about engineering, side projects, and the long road of becoming a software engineer over on this blog — if you are curious where ldash fits into a longer story, my career path post is a good starting point.\nStay in touch If you want to follow what I am building next or support the work directly:\n▶️ Flutter \u0026 dev videos on YouTube — Flutter Explained ⚡ Find me on Nostr via Primal ❤️ Support indie work on Patreon Thanks for reading, and thanks for supporting independent builders.\n⬡ codeberg.org/md-weber/ldash · GPL-3.0-or-later · built with Rust + Ratatui · screenshots\n","permalink":"https://flutter-explained.dev/posts/ldash/","summary":"After months of evening commits, ldash 1.0.0 is out.\nldash is a terminal dashboard for hledger. It turns my plain-text journal into a live overview of net worth, monthly spending, budgets, savings goals, and crypto portfolio — all keyboard-driven, all offline, no browser tab required.\nIf you live in the terminal and use hledger (or want to), this post is for you. New to the world of Plain Text Accounting? It is a small, friendly community built around the idea that your financial data should be a text file you fully own — and ldash is one window into that idea.\n","title":"Introducing ldash 1.0.0 — A Terminal Finance Dashboard for hledger"},{"content":"My view of being a Software Engineer Your browser does not support the audio element. Download the audio file. TLDR Started coding 13 years ago, struggled with basics but stayed determined. First success automating SAP exports, igniting my love for coding. Consulting role led to Open UI expertise and rapid career growth. Freelanced, shifting to full-stack and gaining global experience. Tried YouTube and a Flutter travel app, but plans changed due to COVID. Worked on EV tech at Sono Motors, gaining real-world integration skills. Now thriving on a Flutter team at Sevdesk with strong leadership. Evolved from coder to solution designer, focused on impactful solutions. From Struggle to Breakthrough I would now call myself Software Engineer after around 13 years. I started like everyone else and struggled with even the easiest tasks, and I really felt doomed that I would never be able to code a proper program. Even the easiest methods and function calls nearly killed me and made me think I would never achieve anything. After my first project, I realized that, with a lot of help from my former developer buddies, I felt like I did not really do it by myself. I tried to improve at home but hit so many roadblocks that I thought that’s it.\nI will never forget how it was when I had the task of reading an Excel export in a certain way. Likewise, I needed to order the local “Wisdom Database” and should remove all folders that did not contain anything. I started as I did as a PC user, click on the folder to delete… Until I found out there are several thousands of folders. If I had continued like that, I would have continued like that and deleted folders even today. But during my first student year as a developer, it did not even strike me to create a script for that.\nAfter some conversation, a coworker helped me get back on track, but this showcases how bad my problem-solving skills have been. There was a solution, but I would not come over the first hurdle to identify the problem as a programming problem. My friend supported me to finish the script, but I felt like I still knew nothing.\nAfter that, I fought myself through 3 years of SAP ABAP, SAP Systems, Java SE (with Java Beans), and JSP without the slightest chance of understanding what I was doing there. I was not prolonged in the company, and I still do not know if it really was about my performance or because they did not need another dev, but that gave me two weeks at the end of the student time when I was able to search my own projects.\nFirst Taste of Success I was talking a lot at that time a lot with our product people, and found out that they had an issue with a SAP export that needed to be exported in a certain way. First, I did it manually, but I thought if the PM would need that regularly, maybe I could automate it. It was an epiphany for me at that time. Not only did I understand the problem, but I was also able to conclude that we can easily automate that. And I had two weeks to complete it, so I sat down. Every day as long as I had time, and for the first time ever, I enjoyed my time writing code. Reading through the CSV package helped me understand how to get data from an Excel spreadsheet and reorganize it into a new file the way I wanted it. I felt great!\nBut the best part was that the product manager took the tool, used it and said something that was like knighthood.\nYou are also such a hacker, right?\nI was so surprised, because it really did not feel that way. I was just coding, enjoying my time and creating something useful. Somehow, after that day, programming never felt like a burden again. I was able to create stuff, understand how to Google things, and learn how to read Stack Overflow. Documentation became clear, understandable and manageable. Still, there have been problems I did not understand, but hey, great that it works for me.\nGrowing Through Professional Challenges My next big step was to join a consulting company, and oh boy, that was quite tough. I was a Frontend developer and had no idea what people would expect from me. In the interview, I got tortured with MySQL Database Query questions. Databases was the only subject I had really screwed up during university, and I even got a second chance for the interview because I did not wear a suit during the interview. And in the second interview, they again tortured me with SQL, but somehow I got the job anyway. I heard later that I was really close to not getting in from HR.\nFrom here, I learned a lot of strange things in the beginning. I needed to make a certificate for the Oracle SOA Suite A tool that was just a pain to use, it crashed all the time, was huge to install, and had a manual that was just massive. So I did what every good consultant did and got me a Cheat sheet with all the answers and tried to learn only that and make my certification. After the second attempt, I really got it. Which surprised me quite a lot, but that was great. Luckily, there was a change of plans.\nWe got a new contract in Switzerland, and they needed someone who works with [Oracle Siebel CRM] in a brand-new technology. The new technology was Open UI and was a UI update that was super important because Siebel at that time still relied on ActiveX Elements in Internet Explorer 8, and Oracle paid a massive amount of money to just keep the IE8 support up for their customers. It allowed you to use JavaScript inside the browser and write scripts that were executed on Web Forms you defined. So they invented that new Open UI, which was quite nice, and today, when I understand a bit more, is actually a nice abstraction of the stuff they do in the background.\nDiscovering My Technical Identity So they showed me a screenshot, gave me a short intro into how Siebel CRM works, and with my limited knowledge, I scripted away. I did not really know how this Siebel was working, just that the old forms needed to go away, so I just quickly removed everything on the screen. I wrote everything new - the whole view. There was nothing left from the old form, only hidden elements I needed to press under specific circumstances. Today, I know that was not really intended by the creator. But hey, for the project, I was fantastic with the time plan. After two days and a lot of jQuery (which is included in Open UI), I was able to recreate the whole screenshot, which pushed me from a guy who does not know anything to THE EXPERT in the company about Open UI.\nSuddenly I got contracts, traveled a lot and supported and helped tons of customers about the topic. I had the chance to even launch the new UI for one of the biggest companies in Switzerland. I also created my first library and was invited to the Oracle Open World in San Francisco, my very first public talk that I held. Not only that, but I was quickly moving up the career ranks from Junior Consultant to Senior Consultant within three years. In the last year, I switched my focus from Open UI to a real Full Stack development project because I gained some skills during that time as an Angular Developer. Here, I switched my focus from pure Frontend development to being a Full Stack developer after a college told me:\nYou cannot run away from the responsibility, it is our tool, and it needs to work. Backend or frontend, we need to fix it, and you should also know how it works.\nThat was again a key moment in my life, because it made me realize that it does not matter if my stuff is working, it all needs to work. UI Elements, API calls, Smoke Tests, Pipelines but also Meetings, Project Management, Company Politics. One of my friends who was a freelancer told me that she hates the term “Developer” she is a “Solution Designer” and that stuck with me. I am a Solution Designer, finding problems, seeing how to automate them, and then trying my best to execute. That does not only mean to develop but also to convince people of my solutions, unblock my team from impediments, make a SCRUM master if it is necessary, and so much more. People would call me the girl for everything, and they would probably be right.\nEmbracing the Freelance Journey After a while, I started to freelance and left the company. Which got me in huge trouble and got sentences to hear from my bosses like “I will crush you with my network”… I was really, really happy to leave the company after that, and I started to travel. Which led me to a year in New Zealand, where I was able to work for an American company. Here, I could really flourish. I started as an Angular developer but was able to support and work on an anti-corruption layer. I learned how to code in C# and understood that programming languages are way more similar than I thought. One of the most valuable lessons I learned here is that work is not everything. Because the team was fantastic, and they had a massive integration of their external workers like me as a freelancer.\nBut also I was also involved knee-deep in everything surrounding the company, from CI / CD processes to release tasks, organizing meetings, and writing documentation. Besides delivering code and writing Angular at that time, I loved it there and even got a job offer, which I nearly took but decided against for my family. Which let to a cumbersome time. In that time I thought it would be a great idea to start my YouTube Career, not only teaching my wife every day some new tricks on Flutter, but also explain it to a wider audience was the goal.\nPursuing Entrepreneurial Dreams Together Back home, everything took again quite a turn. My wife and I wanted to become freelancing and create our own app, “World Travel Companion”, but as always, fate had some other ideas. We started to develop the app, but it was in late 2019, which was the year of the Coronavirus, and we were not crazy enough to just create an app that would not be used for the unforeseeable future. Even though we had some money on the side, we had real struggles to get a flat in Germany because security is everything here. No job, → No house, … very bad living here. And YouTube did not get me any money we could live from.\nSo we started the job hunt, and I found a fantastic project at a finance company in Germany, which led to one of the weirdest issues ever. I had too many different industries in my portfolio. I was working for Telco, Health, Finance and even insurance companies. They created a new project and hired consultants to support them by architecting the newest company software architecture, which was quite an impressive step for me and a really great learning experience. After a while, I thought to let them hire me. When considering the finance company role, I realized that while the technical aspects excited me, I hadn’t yet developed a deep connection to the finance industry’s impact.\nFinding Purpose Through Technology So I searched for something meaningful that I could support. And there was a company that I heard a lot about, and that I felt like I wanted to support their mission, Sono Motors, an electric vehicle that should drive with the power of the sun. And it was a blast of a project, it was a startup, so they searched people in every direction with all skills. Whatever you can do, you should do it. I was able to work with React Native on the mobile app, but I also had the chance to create Vehicle Integration stuff. That was my first project where I could see a real-world application of the stuff I am writing, pressing a button in my app opens the door. WOW!\nBut sadly, the dream busted, and the company went bankrupt.\nLanding at My Current Home During my time as a freelancer and while I was working on Flutter Explained, I needed to somehow do my taxes. Therefore, I used a tool called sevdesk a friend of mine told me that they are currently creating a Flutter Team, and I would be a perfect fit, so I decided to apply for the job. And voilà, now I am here. I love to work here at the moment. There are a lot of things I need to learn and even more things we need to improve, but it feels fantastic to be here at the moment. The leadership so far looks promising, and my coworkers are fantastic. I will keep you up-to-date on what my future journey will look like :).\nReflections and Future Outlook I still love programming, I still enjoy it. Even though there are voices saying that AI will take it away and abstract it, I still have a blast discussing with ChatGPT better solutions. I am also finding an incredible joy in working with pipelines and pushing the running times as low as possible. I learned that being a Software Engineer is more than just writing code. Teaching others, finding problems to solve, and explaining why your tasks are important are really as important. I really hope that this short story about my career path will give you some insights and maybe help you in your way.\nThank you for reading, stay curious and if you have time consider supporting me on Patreon.\n","permalink":"https://flutter-explained.dev/posts/personal_dev_story/","summary":"My view of being a Software Engineer Your browser does not support the audio element. Download the audio file. TLDR Started coding 13 years ago, struggled with basics but stayed determined. First success automating SAP exports, igniting my love for coding. Consulting role led to Open UI expertise and rapid career growth. Freelanced, shifting to full-stack and gaining global experience. Tried YouTube and a Flutter travel app, but plans changed due to COVID. Worked on EV tech at Sono Motors, gaining real-world integration skills. Now thriving on a Flutter team at Sevdesk with strong leadership. Evolved from coder to solution designer, focused on impactful solutions. From Struggle to Breakthrough I would now call myself Software Engineer after around 13 years. I started like everyone else and struggled with even the easiest tasks, and I really felt doomed that I would never be able to code a proper program. Even the easiest methods and function calls nearly killed me and made me think I would never achieve anything. After my first project, I realized that, with a lot of help from my former developer buddies, I felt like I did not really do it by myself. I tried to improve at home but hit so many roadblocks that I thought that\u0026rsquo;s it.\n","title":"My personal career path"},{"content":"We already covered in another Article what an HTTP call is and how it works in a Client - Server Architecture. But today, we want to look at how to keep a connection open between the Client and the server to implement a Real-Time Application.\n▶ YouTube video Click to load — this will contact YouTube (Google LLC) and may set cookies and transmit your IP address. Watch on YouTube\nWhy do we need Sockets But what would Sockets benefit be compared to the standard HTTP Request Response method? In modern applications, we want real-time data, and who thinks now at Firebase Store etc. is correct because that is how they do it.\nBefore we had the benefit of WebSockets or Sockets, we had to wait until the server finished a task and make another request to get the data. Because the server never told us we were ready with the new data. Therefore, developers all around the world discovered some quite exciting workarounds like Pooling. At Polling, a client made a request every period (200+ ms) to check if there were new data present. Thanks to WebSockets and Sockets, we have the chance to reduce a load of our servers because we can reduce the calls needed. Furthermore, the server can directly notify the Client of the new information. Real-Time applications are born.\nSockets vs. WebSockets At the beginning of my journey, I tried to use Shelf_WebSockets and connect with my two Terminals, and the result was nothing. Interestingly, I could connect via the terminal clients to the server, but whenever I sent a message, it was just not visible, and the server did not show anything.\nAfter a long time of learning and debugging, I discovered that my Terminal used dart:io and needed a server to work with the same TCP Sockets. Unfortunately, while the WebSocket Server allowed the connections, it could not understand the messages the Terminals tried to send.\nWhy is that the case? WebSockets are upgraded HTTP request that allows the open connection between a client and a server. However, WebSockets are usually used to connect from a Browser or a UI to the server, making it problematic. Some packages allow Terminals to connect against a WebSocket server, but I did not use them. Therefore I needed to change my WebSocket Server to a TCP Socket Server.\nSo the rest of the tutorial will only use a Socket Server and Socket Clients. Still, you can achieve the same with WebSocket Server and a WebSocket Client, for example, websocket_manager that allows Flutter to connect against a WebSocket Server.\nIf you want to know more about Sockets vs WebSockets, I recommend reading the MDN post about WebSockets and the StackOverflow answer. Great, now that we have that out of the way, let’s see how we can develop our application.\nImplementation We will now see the best part of the implementation is that we do not rely on any package. To make this possible default dart is enough to make it work, which is incredible. The only package I added is optional and is called ansicolor and allows to make prints in the console a bit more colourful.\nI created a basic barebone Dart project without anything inside but a terminal executable. After all, we do not need the boilerplate from the Server app because we want to use Sockets :).\nNow I deleted everything in the bin folder and created three files client.dart, server.dart and terminal_service.dart. In the Client.dart, we will collect all information about the Client, how he connects to the server and the message he sends. In the end, we can start multiple clients against a single server. The second file is the server.dart inside here, we write everything to receive messages from multiple clients and notify all clients that there something new happens.\nLast but not least, we have the terminal_service.dart is just a mini service containing different print functions for different colours. The result after the tutorial will look something like this.\nSetup the Server First, we start as always within the main function. Inside here, we want to find the local IP address and allow us to find just an unused IP address. Then we create a ServerSocket and bind the IP and a port. In our case, the port is fixated on 3000. after that, we just let the server listen to incoming connections, so whenever someone connects to the server, the callback is in the server.listen(callback) will be executed.\ndart 1 2 3 4 5 6 7 8 9 10 Future\u003cvoid\u003e main() async { final ip = InternetAddress.anyIPv4; final server = await ServerSocket.bind(ip, 3000); print(\"Server is running on: ${ip.address}:3000\"); server.listen((Socket client) { handleConnection(client); }); } Whenever a client is connecting to our server, we call handleConnection. Inside, we want to inform the server of an incoming connection. The socket we receive in the handleConnection is the information on communicating to that specific Client. If you want, for example, to create multiple players, you can save that socket to have a reference between player and socket to send messages between specific players. Now we must listen to the Client if the Client sends the server some messages.\ndart 1 2 3 4 5 6 7 8 9 List\u003cSocket\u003e clients = []; void handleConnection(Socket client) { printGreen( \"Server: Connection from ${client.remoteAddress.address}:${client.remotePort}\", ); client.listen( ... ); } Before, we already had the server.listenwhere the server waited for connections. Now we haveclient.listen, so we on the server wait for the client to send us some notifications. The client.listenfunction has some information we have to pass in. The first part is how to handle messages from the Client. So we will receive a Uint8List message that is just a basic ByteString, and because we will be in complete control of the Client, we know that this will be a plain string so that we can transcode it withString.fromCharCodes(data).\nIn that message, we want our users to send the player name so we can inform every Client that is already connected to the server.\ndart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 client.listen( (Uint8List data) async { final message = String.fromCharCodes(data); for(final c in clients) { c.write(\\\"Server: $message joined the party!\\\"); } clients.add(client); client.write(\\\"Server: You are logged in as: $message\\\"); }, onError: ... onDone: ... ... ) Implement the Client First, we create another file called client.dart in our Dart Project. Here we will implement the client application that will connect to our server. The Client works similar to the server and should be a standalone Dart application. Therefore, we need another main function. In this main function, we connect with a Socket to our server with the IP we get from the server command:\ndart 1 2 3 4 Future\u003cvoid\u003e main(){ final socket = await Socket.connect(\"0.0.0.0\", 3000); print('Connected to ${socket.remoteAddress.address}:${socket.remotePort}'); } When we execute the client.dart file without anything further, we will already get the information on our Terminal where the server is running. It should look something like this.\nssh 1 2 ➜ dart ./bin/client.dart Connected to: 127.0.0.1:3000 ssh 1 2 3 ➜ dart ./bin/server.dart Server is running on: 0.0.0.0:3000 Server: Connection from 127.0.0.1:53419 Therefore we can see that the server already receives the connection and keeps the connection open for the IP 127.0.0.1:53419. The IP points are also the same computer, but the IP and the Port could be entirely different for your implementation. Great, so the connection is already stable so let’s send some messages from the Client to the server and see how we can handle them. We will ask the user for his name and send the information to the server.\ndart 1 2 3 4 5 6 7 8 9 10 // Ask user for its username String? username; do { print(\"Client: Please enter your username\"); username = stdin.readLineSync(); } while (username == null || username.isEmpty); socket.write(username); We first define a variable username that could be null, and in the do-while-loop, we ask the user for a terminal input to enter the username. If the username is null or empty, we ask him again until we get the needed information. After that, we call socket.write(username), which sends the information directly to the server. But if we restart the server and the Client now, we will see nothing has changed. The message is now only sent to the server; if we recheck the server, we see that we send the message to the Client.\nclient.write(\"Server: You are logged in as: $message\");\nOn the other hand, the Client does not listen to server messages and cannot show what the server sends. So let us make the Client smarter and allow it to receive messages sent by the server.\ndart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 socket.listen( (Uint8List data) { final serverResponse = String.fromCharCodes(data); printGreen(\\\"Client $serverResponse\\\"); }, onError: (error) { print(\"Client: $error\"); socket.destroy(); }, onDone: () { print('Client: Server left.'); socket.destroy(); }, ); If we check the socket, we can see that it also provides the listen method and also here, we have the chance to implement the same three methods as on the Server side. Therefore we implemented them nearly the same. The only difference is that the onData method now receives the message and directly prints them into the console.\nIf we start up now the Server and Client, we should be able to see something like this:\nssh 1 2 3 ➜ dart ./bin/server.dart Server is running on: 0.0.0.0:3000 Server: Connection from 127.0.0.1:54384 ssh 1 2 3 4 5 6 ➜ dart ./bin/client.dart Server: Connected to: 127.0.0.1:3000 Client: Please enter your username Max Client Server: You are logged in as: Max And if we create another client the following will happen:\nssh 1 2 3 4 5 ➜ dart ./bin/client.dart Server: Connected to: 127.0.0.1:3000 Client: Please enter your username Mahtab Client Server: You are logged in as: Mahtab ssh 1 2 3 4 5 6 ➜ dart ./bin/client.dart Server: Connected to: 127.0.0.1:3000 Client: Please enter your username Max Client Server: You are logged in as: Max Client Server: Mahtab joined the party! ssh 1 2 3 4 ➜ dart ./bin/server.dart Server is running on: 0.0.0.0:3000 Server: Connection from 127.0.0.1:54384 Server: Connection from 127.0.0.1:54415 Conclusion We now have a successful Socket Server running and multiple clients connected. After this tutorial, you should have the power to create excellent applications that need real-time experience. That can be integrated with Games but also in Tools where collaboration is vital. You can find the tutorial project on Codeberg. Feel free to check it out, and if there are any thoughts, please let us know. Thanks for reading, and till the next post.\nThank you for reading, stay curious and if you have time consider supporting me on Patreon.\n","permalink":"https://flutter-explained.dev/posts/a-terminal-real-time-application-with-dart-sockets/","summary":"We already covered in another Article what an HTTP call is and how it works in a Client - Server Architecture. But today, we want to look at how to keep a connection open between the Client and the server to implement a Real-Time Application.\n▶ YouTube video Click to load — this will contact YouTube (Google LLC) and may set cookies and transmit your IP address. Watch on YouTube\n","title":"A terminal real time application with Dart Sockets"},{"content":"Running the first server is a fantastic experience for every developer.\nIt gives you many options and possibilities and improves your general understanding of software engineering. After we learned in my previous videos already how to start a server locally, we want in this article to learn how to make our services available on the world wide web so that you can access them from every device.\nDeployment Software deployment includes all activities that make a software system available to use. - Wikipedia\nIn our use case, we want to access our server from every device connected to the Internet and not only our local device in front of us. In professional teams, that task is automated in most cases and transforms\nquickly. Into continuous deployment where you work on your code, push to a repository, and the deployment gets automatically triggered. But in smaller teams or smaller organizations, the preferred way is usually for a skilled professional to perform that task. And because we are skilled professionals, we do exactly that today.\nPrerequisites We have to prepare just a few things to get started in the beautiful world of deployment. The first thing that we need is a physical server that will run our software server :). For this reason, we will use Heroku, because it allows us to run our software for free in a small server Virtual Machine (VM) that we can scale up if we want.\nWe also need a software service that we already built in the videos mentioned above. The service we want to deploy will use the shelf server from Dart that we already run locally and make our first requests. But this will also work if you use a aqueduct server or a conduit server.\nSummary of what we need today:\nHeroku Account\nRunning Software Server\nNo previous knowledge about deployment processes\nGetting started After you successfully create an account on Heroku, you will probably see a page that welcomes you to Heroku. From here, you could also create a new app, but we will do it with the Heroku CLI.\nHeroku CLI Now that we have that covered let us jump right into it. To begin our journey to deploy something on Heroku, we need to install the Heroku CLI. Then, check out the link of the Heroku CLI and select the system that fits your operating system.\nGreat, the Heroku CLI will help us deploy our Server to the Heroku server. After the installation, we first have to login against the Heroku system. For that, execute Heroku login in your terminal. After executing the command, your default web browser will open and allow you to log in to Heroku.\nCreate a new Heroku app The most convenient way to create a new Heroku app is via the CLI. For that, open a terminal and navigate to your workspace in which your project is. In our example, it will be in ~/dev/dart-server. Now we want to create our app. We execute Heroku create \u003cname-of-your-app\u003e in our example. We call the app fe-dart-server. If you do not pass a name,\nit will create a random app name for you.\nbash 1 2 3 4 5 heroku create fe-dart-server Creating ⬢ fe-dart-server... done https://fe-dart-server.herokuapp.com/ | https://git.heroku.com/fe-dart-server.git As a result, Heroku delivers us two URLs. The first one is the URL directly to our app. Currently, we do not have an application running on https://fe-dart-server.herokuapp.com/.Therefore, you will find the documentation link of Heroku if you open it. The second link is the internal git server of Heroku, from which it will use your source code to build the project. We will need to add a new remote to git to push our Dart project.\nbash 1 2 3 # If you have not initialized your project with git git init git add remote heroku https://git.heroku.com/fe-dart-server.git ** Hint: It could be that if your project was already in git, it was already added with the Heroku create command**\nNow that your app is registered to Heroku, we have to set up a buildpack.\nHow Heroku works Now it is essential to know how Heroku works. A build pack is responsible for transforming your deployed source code into a slug, which can then be executed by a dyno. You can read more about how Heroku works here. So before we go deeper into the topic, let’s quickly check what a slug and a dyno are.\nA slug is a bundle of your source, fetched dependencies, the language runtime, and compiled/generated output of the build system - ready for execution.\nDynos are isolated, virtualized Unix containers that provide the environment required to run an application.\nSource: devcenter.heroku.com\nSet up a build pack for Dart Unfortunately, Heroku is not yet supporting Dart with an official build pack. Therefore, we have to take advantage of the fantastic Dart \u0026 Flutter Community, which has created already a build pack that we can use. We will use in this tutorial the most starred build pack by igrigorik.\nTo use the build pack, we will have to tell Heroku to use a specific download URL for the Dart language and configure the build pack we want to use. To find a Dart SDK URL, we check the Dart Archive page. Then, we select Linux and the version we would like to install. This example case is version 2.16.2`, which is the current version. Now right, click on Dart SDK and copy the link address. We will need it in a second.\nNow it is time to set the Dart URL and our BUILDPACK_URLfor our Heroku app by executing in our terminal.\nbash 1 2 3 4 5 6 7 8 9 10 11 heroku config:set DART_SDK_URL=https://storage.googleapis.com/dart-archive/channels/stable/release/2.16.2/sdk/dartsdk-linux-x64-release.zip Setting DART_SDK_URL and restarting ⬢ fe-dart-server... done, v3 DART_SDK_URL: https://storage.googleapis.com/dart-archive/channels/stable/release/2.16.2/sdk/dartsdk-linux-x64-release.zip heroku config:add BUILDPACK_URL=https://github.com/igrigorik/heroku-buildpack-dart.git Setting BUILDPACK_URL and restarting ⬢ fe-dart-server... done, v4 BUILDPACK_URL: https://github.com/igrigorik/heroku-buildpack-dart.git Now it is time to push our source code to Heroku by pushing our source code to the remote git that we got when we created our Heroku app.\nbash 1 2 3 git add . # Adds all files to git in this repository git push --set-upstream heroku main # Sets the upstream branch to heroku main and pushes all files If you are doing it in the terminal, Heroku will give you a lot of logging information about the build process.\ntext 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 remote: -----\u003e Discovering process types remote: Procfile declares types -\u003e (none) remote: remote: -----\u003e Compressing... remote: Done: 195.9M remote: -----\u003e Launching... remote: Released v7 remote: https://fe-dart-server.herokuapp.com/ deployed to Heroku remote: remote: Verifying deploy... done. To https://git.heroku.com/fe-dart-server.git \\trefs/heads/main:refs/heads/main\\t75c0e7f..b4f1198 Done The log above tells us that everything was successful, but one step is missing. First, we need to declare the dynos we want for our app. For that, we need to create aProcfilein the root directory of our project. Then, we enter the dyno and what it should start to execute our server. In our case, we execute thedart_server.dartin the bin folder.\n:title=Procfile 1 web: ./dart-sdk/bin/dart bin/dart_server.dart Hint: The Procfile does not have a file extension like.txtor.js.\nIf we now commit and push again to the Heroku git server we are ready to see our server in action.\nbash 1 2 3 git commit -m \\\"Added Procfile to setup the dyno\\\" git push --set-upstream heroku main 🎉 Great, if everything worked well, you should have now your first running Dart Server on Heroku.\nTroubleshooting As always, some things could go wrong, and I try to add a collection that we found out during our live stream.\nDynamic Port Heroku does not provide you static port, so you will get a new port every time the instance is started. Especially in the free plan, that happens pretty frequently and therefore, you must take the PORT provided by the\nEnvironment variablesof Heroku.\ndart 1 2 3 4 5 6 7 8 9 10 11 12 13 var env = Platform.environment; var port = env.entries.firstWhere((element) =\u003e element.key == 'PORT', orElse: () =\u003e MapEntry('PORT', '8080')); var server = await shelf_io.serve( logRequests().addHandler(router), '0.0.0.0', int.parse(port.value)); Replace localhost with 0.0.0.0 Heroku is pointing to itself while setup a server you will need to changelocalhost to 0.0.0.0\ndart 1 2 3 var server = await shelf_io.serve( logRequests().addHandler(router), '0.0.0.0', int.parse(port.value)); Wrapping up Great, we did it. With these steps, we published our server to Heroku and made our very first deployment possible. The next milestone is to create a helpful app out of this server. We were maybe starting with a small quiz app that allows you and your friends to learn more about development. For that, you will probably need more insights into the shelf_router package or an even bigger solution like Conduit. Feel free to share your first examples with me on Twitter with the Hashtag #FlutterExplained. I cannot wait to see your results!\nThank you for reading, stay curious and if you have time consider supporting me on Patreon.\n","permalink":"https://flutter-explained.dev/posts/deploy-dart-server-on-heroku/","summary":"Running the first server is a fantastic experience for every developer.\nIt gives you many options and possibilities and improves your general understanding of software engineering. After we learned in my previous videos already how to start a server locally, we want in this article to learn how to make our services available on the world wide web so that you can access them from every device.\nDeployment Software deployment includes all activities that make a software system available to use. - Wikipedia\n","title":"Deployment of a Dart Server on Heroku"},{"content":"Setup Code Linting for a Flutter project In the beginning, let me say that additional Linting in Flutter is a controversial topic. On one side, many love code linting, because it allows us to focus on crucial parts of our code. However, some people are not fond of it because it restricts them and leads to false build errors. But before we start the discussion, let us begin with what code linting is and how we can use its full potential.\nCode Linting is an automated verification that your code is correct. There is always a Linter that we all use in our day to day work. In editors like VSCode and Android Studio, we receive errors when our code is not unnable.\nThe visualisation of build errors are already features of our Linter. This integrated Code Linter is a tool that checks your code for build problems, that means you would not even be possible to run your application. We do not have to search for errors in our code, and when everything is green, we are sure that our code is executable.\nThanks to modern tools, we can extend these rules and check our current project for more than just broken code. For example, we can tell our Linter that we want to check for wrong code styling. In Dart and Flutter the additional lint rules are managed by a file called analysis_options.yaml. If you have never heard about a yaml file extension, it is just a convenient way to structure a file that allows you to create tree structures with two spaces. Feel free to read more about the .yaml file extension here.\nOur Mission: Enforce single quotes in our project Let us assume we would force all our developers to work on our project,\nthat every string should be done with a single quote. Our IDE should show it immediately, like in the image below.\nTo achieve that the static code analyzer of Dart and Flutter recognize that mistake, we must create an analysis_options.yaml responsible for our whole project gives our Dart analyzer instructions that run in the background and verifies our code. We can create the analysis_options in the root of our project, and most IDE’s like Android Studio or Visual Studio Code will right away understand what it needs to do with it.\nNow, let’s take a closer look into the analysis_options file. Inside of the analysis_options, we can modify the behaviour of the analyzer and the linter.\nThe Analyzer \u0026 Linter In our first section in the common analysis_options.yaml file is usually the analyzer. Here we can configure a more general part of how we want to check our code. Firstly, we can set up if we want to show errors, warnings, or as information for specific rules. Secondly, we can exclude files and folders from the checking system. Moreover, we can ignore specific rules. Last but not least, we have the chance to introduce additional strict type checking and experimental behaviour like no slow checks or super-mixins.\nTo use now the main information that we registered to the Analyzer, we have to specify the rules that we want to apply in our project. Therefore, we use the Linter section of the analysis_options.yaml. In the linter section, we define which rules are applied to our project. There are around 180 rules that you can specify and make them right away visible in your application. To explain, all of them would bust this blog post, so feel free to look at the list of linting rules you can specify at the Linter for Dart site.\nLinting Rules At the time I write this post, there are three different categories of Linting Rules. The first is the Error Rules, and they are possible coding errors. Secondly, we have the Style Rules that define code style matters, like a single quote or double quote. It does not hint whether your code is stable or not, but it helps align the whole codebase. The pub rules follow both. This set of rules defines how a pub package has to behave; it includes only two rules on how to name a package and sort dependencies in your pubspec.yaml.\navoid_init_to_null As the name already states with this linter rule, you do not allow anymore to initialize a variable with null. But why could this be helpful? In Dart, every variable that is not specified with a value is automatically set to null. There is no concept of empty memory or any other trap that we could fall into. With that in mind, a specific declaration of a variable to null would only bloat our code and is unnecessary and unneeded.\nuse_string_buffers Another fantastic rule that many developers are not really aware of is a more performant way to concatenate strings. The String Buffer helps you improve the concatenation of Strings and allows you to do it in the most performant way. To make sure that all contributors in your code concatenate strings efficiently, we can set the use_string_buffers style rule.\nprefer_double_quotes The prefer double quotes rule allows you to take control if you want to enforce a specific quote style. Here we prefer in our code base double quotes but also the single quote rule exists and makes it possible to enforce quote style. This is especially helpful if you work in a multilanguage team because Keyboard layouts differ from country to country. In contrast, in English and American speaking country, the single quote is easier accessible and mostly used in other countries like Germany, the double quote is usually prefered. This rule leads to clear information on how the maintainer or the owner of a package or project wants to work in general.\nThis is also the rule that we will use to finally solve our problem and enforce double quotes for the whole project.\nThe Solution Alright now that we know how the Linter and the Analyzer work lets solve our goal for this blog post, we want to enforce every developer who works on our codebase to prefer double quotes, and if they do not, we want to really show it as an error. The first thing we have to do is to define the Analyzer with the correct severity of the issue. In our case, this would be “error”. Next, we just defined in the pubspec.yaml our linter with the new rule that we want to add.\nNow after we have specified the rule and the severity of the enforcement we can already see in our IDE the errors appearing.\nIf we now run dart analyze in our terminal inside our project, we receive a full analyzing report. Now we can use this command inside our terminal. If we use this command now in our CI / CD chain, the build will fail, and our team would have to fix it to merge it in our project.\nLint Rules as a package As always, there are fantastic packages that come with a predefined selection of rules that makes it easier to set up the first baseline that you want to use in your project. Let us first have a look at how we can include them in our project.\nInstall a third party linting rule set In order to add a linting rule set we have to first add the dependency to the pub.dev package in our pubspec.yaml. As an example we want to add the Lint package to our project.\nThe next step is to import the rules from the package into our analysis_options.yaml.\nAs soon as you open now the different files, you will now recognize that the package’s linting rules are already taken into account and are ready to use. Let us assume that you do not like a rule. You can easily overwrite the behaviour by including the linter and analyzer. Your rules will overwrite the package’s rules, with that you will always have control over the linting.\nLint Package Pascal Welsch creates the first Lint package, and it includes a baseline of lint rules for Flutter and Dart Projects. You can extend or exclude rules afterwards if you use this package, but it is created with consumers. That means if you are not necessarily working on the Flutter project. This should be your way to go.\nPedantic The second package that I want to introduce you is the so-called pedantic package. The Flutter team created the pedantic package to support a set of rules that is usually way more restrictive in terms of usage and allowances and is a bit over-engineered from time to time.\nConclusion In this post, we learned how to use the Linting Rules to our advantage and enforce rules so that every developer who collaborates with us works in the same way. To generate these rules and discuss them in a team could be tedious, and many people would say that it is not worth the effort. But if the conversation and discussion start now, you have the right tools to join the discussion and give some valuable insights.\nThank you for reading, stay curious and if you have time consider supporting me on Patreon.\n","permalink":"https://flutter-explained.dev/posts/code-analysis-and-linting-in-flutter-and-dart/","summary":"Setup Code Linting for a Flutter project In the beginning, let me say that additional Linting in Flutter is a controversial topic. On one side, many love code linting, because it allows us to focus on crucial parts of our code. However, some people are not fond of it because it restricts them and leads to false build errors. But before we start the discussion, let us begin with what code linting is and how we can use its full potential.\n","title":"Code Analysis \u0026 Linting in Flutter and Dart"},{"content":"Repositories that are worth mentioning The first Flutter Repository is created by Robert Felker, aka Solido. You can find a great list of resources that contains a fantastic amount of knowledge about Flutter. It includes further Ressources like Content Creators, Videos, Tutorials and example Repositories. And the best part, thanks to over 268 contributors the project is still in active development and receives updates regularly. It follows a strict “How to contribute” – guideline makes sure to\nread it carefully before you add your next fantastic idea.\nFlutter Roadmap You are a bit lost on your track to enlightenment with Flutter? Search no more the Flutter Roadmap got you covered.\nIt contains all essential parts of Flutter Software Development that you could think. This package offered me a personal\nLearning path. Additionally, I was able to track your personal learning goals. The Main Contributor is Oleksandr Leuschenko,\naka. olexale he also is the author of arkit_flutter that allows AR development with Flutter.\nThe official Flutter Gallery The Flutter Gallery is officially inside of the Flutter Teams Repository. The Gallery contains a lot of full-fledged app examples. You will find demo applications for eCommerce Applications, Financial Services, Travel application and E-Mail Client. Thanks to the code examples and the fantastic website, I was able to convince friends and partners about Flutter.\nThe Gallery is a fantastic start of your Flutter career and additionally helpful if you want to convince your friends, partners and clients on how great Flutter is. Last but not least, you can check out the whole repository and start it locally.\nFilledStacks Tutorials FilledStacks is a YouTuber and Content Creator around Flutter and Dart and has a great library of Tutorials that he supports with a Blog and YouTube videos. I highly recommend you to check out his repository in which he shares many insights on how to implement various topics like Firebase Implementation, Mouse Hover, Location Services and State Management. FilledStacks was one of the first YouTuber I found, and that motivated me to stick with Flutter and learn more.\nMais Flutter Ressources One of the newer repositories in which Mais collected all her resources for Flutter Development. She collects\nan extensive range of information like quick linking of the official documentation, YouTube channels in 2020,\nCourses, Tools and many more.\nAwesome Flutter Talks Another Repository that I look frequently onto is the Awesome Flutter Talks. Here Rahiche collected all important talks in the last couple of years and the list is still growing.\nThanks for reading and consider a subscription to my patreon.\n","permalink":"https://flutter-explained.dev/posts/top-7-flutter-packages/","summary":"Repositories that are worth mentioning The first Flutter Repository is created by Robert Felker, aka Solido. You can find a great list of resources that contains a fantastic amount of knowledge about Flutter. It includes further Ressources like Content Creators, Videos, Tutorials and example Repositories. And the best part, thanks to over 268 contributors the project is still in active development and receives updates regularly. It follows a strict “How to contribute” – guideline makes sure to\n","title":"Repositories that are worth mentioning"},{"content":"The app helps me to prevent the loss of my future recipes. I’m still working on my project, but meanwhile, I wanted to create also a web project out of it. So I decided to create a Flutter Web Project and deploy that to Firebase Hosting. If you want to publish it under GitHub Pages, we have also an article for that.\nFirebase Hosting provides fast and secure hosting for your web app, static and dynamic content, and microservices.\"\nFirebase Documentation\nIn this article, I would like to share my experience with you. So let’s start.\nPrepare the Flutter web project To deploy a Flutter web project, we have to build the project at first with release build mode of our web app. But before we start with that, let’s see which different kind of build modes we have in Flutter.\nFlutter Build Modes In Flutter, we have three different build modes for different usages:\nDebug mode: During development and to use hot reload.\nProfile mode: To analyze the performance\nRelease mode: To release the app\nWhen we create a release build for our app, the bundle is minified, and tree shaking has been performed. So let’s start and build the app in release mode.\nCreate a release bundle Now to run the flutter build, we have to add the release flag to the build function. Open the terminal and navigate into your project folder after that enter the following command.\nbash 1 flutter build web --release The release build of my save_recipe app looks like following:\nAfter we finished the setup of our Flutter project, it’s now time to set up our Firebase Hosting.\nFirebase Hosting Setup To set up our project for the deployment to Firebase Hosting, we have to follow some steps that we will go through them step by step.\n1. Create a Firebase project The first step to set up our Firebase Hosting configuration is to create a project in Firebase. Therefore, we have to sign in to the Firebase console with our Google account.\nTo create a new project in Firebase, we will go to the Firebase console’s project overview and click on Add Project. Next, we give the project a name and click on continue. Here we can choose if we want Google Analytics for our project or not, and after that, we click on create project.\nNow with the project in place, we are set and ready to take the next step. We have to install the Firebase CLI into our project.\n2. Install the Firebase CLI There are different options to create the Firebase CLI. In this article, we will use npm to install it on mac. For that, I will open the Terminal and run the following command.\nbash 1 npm install -g firebase-tools After executing this command I get directly an error message:\nbash 1 2 3 4 5 6 7 8 9 10 11 12 13 14 npm WARN checkPermissions Missing write access to /Users/\u003c\u003cusername\u003e\u003e/.npm-global/lib/node_modules/firebase-tools/node_modules/string_decoder npm WARN checkPermissions Missing write access to /Users/\u003c\u003cusername\u003e\u003e/.npm-global/lib/node_modules/firebase-tools/node_modules/through2/node_modules npm ERR! code EACCES npm ERR! syscall access npm ERR! path /Users/\u003c\u003cusername\u003e\u003e/.npm-global/lib/node_modules/firebase-tools/node_modules/archiver-utils/node_modules/readable-stream npm ERR! errno -13 The error message describes that I do not have the right permissions on the npm folder. To solve this problem I had to run the following command and enter my password:\nbash 1 sudo chown -R 501:20 \"/Users/\u003c\u003cusername\u003e\u003e/.npm\" And last but not least we should fix the permission problem with the sudo command. After that, I should execute again the command to install the Firebase CLI again.\nbash 1 sudo npm install -g firebase-tools 3. Initialize our project Now it is time to connect our local project to our Firebase project. For this purpose, we have to navigate to the root of our project in the terminal at first. And after that initialize a new Firebase project with the following command.\nbash 1 firebase init With this command, we will set up our project directory and some Firebase features. As soon as I execute the command, I get the following error:\nbash 1 zsh: command not found: firebase After some researches, I figure out a solution from durul in [GitHub]https://github.com/firebase/firebase-tools/issues/113#issuecomment-301613705, how to fix it. As the global variable for the zsh is not correctly set, we should set it up at first. To solve this issue, I run this command.\nbash 1 alias firebase=\"`npm config get prefix`/bin/firebase\" After that, we will execute the previous command again and I get a promising answer now.\n4. Project Setup In the next steps, we should configure the Firebase CLI features for our project. To do that, we can navigate between different answers in each question and select our answer with the space key and after that hit the enter key. For the questions with a yes or no answer, we should type just “y” or “n”.\nWhich Firebase CLI feature do you want to set up for your folder? Hosting\nSelect your default firebase project, if you have. In my case, I will select save-recipes project and hit enter.\nWhat do you want to use as your public directory? build/web\nThe answer to this question should be the path to our index.html file in our web bundle.\nConfigure as a single-page app? y\nFile build/web/index.html already exists. Overwrite? N\nNow our Firebase initialization is done. If we have a look at our project, we can see that Firebase creates two new files in the root of our local project.\nThe .firebaserc file stores our project aliases.\nAnd the firebase.json contains the list of our project configuration. If you like to learn more about how to configure customized hosting behaviour, have a look in the Firebase documentation.\n5. Deploy our project We are almost there. The last step is now to deploy our website. For that, we should run this command.\nbash 1 firebase deploy If everything is going well, we should get the URL to our deployed website.\nHurray!! Here we go, this is the URL to my save-recipes project:\nhttps://save-recipes.web.app\nNow if we open the link to our website, we should see our web project, which is in our index.html file.\nIf we open the URL and see the following screen in our browser, it means that we didn’t set the right public directory for our project, which was the third question by the project setup.\nTo solve this problem, we should just adjust the “public” directory in the firebase.json file to the right path. The directory should point directly to the index.html folder in our web bundle in our local project.\nAfter we change this directory, we should save it and deploy our project again. That means execute again our last command in terminal.\nbash 1 firebase deploy Now it should work everything as desired, and we should be good to go.\nConclusion Creation of a Flutter web project is fast, and you can do it with a single command. In this article, we learned how to deploy our Flutter web project to the Firebase Hosting, which is also possible in a couple of steps.\nI highly recommend you to give it a try and let me know in the comments about your experiences.\nThanks for reading and think about supporting me on Patreon! 🎉\n","permalink":"https://flutter-explained.dev/posts/firebase-hosting-for-flutter-web-projects-in-4-easy-steps/","summary":"The app helps me to prevent the loss of my future recipes. I’m still working on my project, but meanwhile, I wanted to create also a web project out of it. So I decided to create a Flutter Web Project and deploy that to Firebase Hosting. If you want to publish it under GitHub Pages, we have also an article for that.\nFirebase Hosting provides fast and secure hosting for your web app, static and dynamic content, and microservices.\u0026quot;\n","title":"Firebase Hosting for Flutter Web Projects in 4 easy steps"},{"content":"General Serialization Serialization is the process in computer science to convert an object into something that can be saved in a database or be sent via a network request. Today we want to transform a JSON String that we receive from an API and transform it into an instance of an object.\nTo get our Person information as a String, I will work in the following example with the Random User Generator. This can generate random user information and provides us with an API to receive a JSON String.\nBasic Network Request – Example App With the help of the RandomUserAPI, I created an application that shows us a list of users as soon as we open the app. We create this Application together in the video for a basic network request. In the video, we use the manual approach for Flutter JSON Serialization, and with this blog post, we changed that to a more automated process.\nIf you search the source code for this project and this article please you will find everything here.\nManual Flutter JSON Serialization To get a better understanding of why we should prefer automatic Flutter JSON Serialization, we have to take a step backwards. For that, we first take a look at how the manual serialization works precisely.\ndart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Person { String name; String phoneNumber; String imageUrl; Person({this.name, this.phoneNumber, this.imageUrl}); Person.fromJson(Map\u003cString, dynamic\u003e json) : name = '${json[\"name\"][\"title\"]} ' '${json[\"name\"][\"first\"]} ' '${json[\"name\"][\"last\"]}', phoneNumber = json[\"phone\"], imageUrl = json[\"picture\"][\"thumbnail\"]; } In the code snippet above, we created a new person object that we receive from our API. As you probably already have seen, we have to write all the key strings into the class and pollute our class with API information. Additionally, we come into the trap that if we want to add or remove an attribute, we have to change it all over.\nThat makes the maintainability pretty hard. Especially if the API changes and we have to create it from scratch. That would lead to a lot of searches and replacements, and we will lose all IDE supports.\nBenefits No boilerplate surrounding the solution\nThere is no setup required, so you can start directly accessing the parameters\nDisadvantages You have to write every line yourself\nTypos can happen and reduce the stability of your application\nFor every new Field that you want to add, delete or modify we have to modify the code in the model\nHigher maintenance costs especially for larger projects or with changing API´s\nGenerated Serialization Now that we understand the issues with self-written serialisation let’s have a look at generated Flutter JSON Serialization. There is at the moment not a built-in solution in the Flutter framework, but there are plenty of perfect packages on pub.dev for this problem. In this article, we will have a closer look at the json_serializable package.\nThe package works powerfully with the build_runner package and allows us to generate the “fromJSON” and “toJSON” functions, without writing all keys of the JSON. We only have to set up our models correctly, annotate them accurately and provide two functions inside. But enough of the words, we want to see some code.\nDependencies Before we can begin to work with the json_serializable package, we have to add first some dependencies into our project.\nyaml 1 2 3 4 5 6 7 8 9 10 11 12 dependencies: flutter: sdk: flutter cupertino_icons: ^0.1.3 http: ^0.12.0+4 json_annotation: ^3.0.1 dev_dependencies: flutter_test: sdk: flutter build_runner: ^1.8.1 json_serializable: ^3.3.0 The json_annotation is the only dependency that actually has to be inside of our project. The build_runner and json_serializable are just development dependencies and will not be part of the final bundle.\nModify the model dart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 part 'person_model.g.dart'; @JsonSerializable() class PersonModel { NameModel name; String phone; String email; PictureModel picture; PersonModel({this.name, this.phone, this.email, this.picture}); factory PersonModel.fromJson(Map\u003cString, dynamic\u003e json) =\u003e _$PersonModelFromJson(json); Map\u003cString, dynamic\u003e toJson() =\u003e _$PersonModelToJson(this); } Line 1: With the part person_model.g.dart we give the PersonModel class the possibility to access the methods inside the person_model.g.dart file. The file will be generated later from the built_runner.\nLine 3: The @JsonSerializable() annotation tells the build_runner that this class has to be concerned for the generation of a new file and creation of a serialization.\nLine 5 + 8: For objects inside our JSON we have to create their representing Model classes for NameModel and PictureModel. The new models will also be annotated with @JsonSerializable() and will also get the two new methods from line 12 and 14.\nLine 12: The new factory constructor fromJson is close to our old method. But instead of creating a new Instance of the PersonModel, we call a method _$PersonModelFromJson(json). This method will be generated later with the help of built_runner.\nLine 14: The toJson method returns as expected a Json (in Dart a Map between String and dynamic). To receive the map we call the generated function _$PersonModelToJson(this), and pass the current instance inside.\nUnleash the power of the built_runner After we have successfully created our model with the necessary annotations and functions, we are ready to go for the built_runner script. We open our project in the terminal and execute one of the following commands.\nbash 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // Inside of Flutter projects // Generates the generate files once flutter pub run build_runner build // Watches the model files and generates on each change flutter pub run build_runner watch // Inside of Dart projects // Generates the generate files once pub run build_runner build // Watches the model files and generates on each change pub run build_runner watch For the case that you have a regular dart project, I also added the commands for the consistent Dart packages creation. This command will create for you the additional *.g.dart files. These files can be inserted into .gitignore, as everyone in the team can execute this command.\nLet us have a more in-depth look into the generated file from the serialisation. Here you can see the two functions that we call in the fromJson and toJson of the partial class.\ndart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 // GENERATED CODE - DO NOT MODIFY BY HAND part of 'person_model.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** PersonModel _$PersonModelFromJson(Map\u003cString, dynamic\u003e json) { return PersonModel( name: json['name'] == null ? null : NameModel.fromJson(json['name'] as Map\u003cString, dynamic\u003e), phone: json['phone'] as String, email: json['email'] as String, picture: json['picture'] == null ? null : PictureModel.fromJson(json['picture'] as Map\u003cString, dynamic\u003e), ); } Map\u003cString, dynamic\u003e _$PersonModelToJson(PersonModel instance) =\u003e \u003cString, dynamic\u003e{ 'name': instance.name, 'phone': instance.phone, 'email': instance.email, 'picture': instance.picture, }; Here are all the strings that we had to create beforehand inside of these methods. Thanks to built_runner they getting now generated for us. If you take a look at line 18, you can see that even the child models are generated correctly. If we now change something in our class and execute once more the build runner (or let it watch), then we will see how it gets added to the list automatically.\nBenefits Modifications to the class are instantaneously reflected\nLower maintenance due to less written code\nTypes are directly set via the attributes\nNo magic happens, the generated files are in the project\nDisadvantages Initial setup is increased\nThere is some boilerplate involved\nYou have to make sure everyone on the team is aware of the build_runner function (possible solution would be a script or a good readme.md file)\nGenerated files could distract from the real model files\nPackages for Flutter JSON Serialization There are several other packages that you can use for generated JSON Serialization.\nbuilt_value / built_collection The built_value or built_collection can handle JSON Serialization in a very similar way as we did in json_serializable. But add beneficial functions like immutability, comparability and other quality of life functions.\ndart_json The dart_json has the benefit that it is absolutely dependency less. If you search for a solution with as few dependencies as possible this package is your best bet.\nJSON Web parser There is some JSON Web parser that creates out of your JSON a valid dart model for you. You can copy a JSON into the left side and copy the model on the right side into your application.\nConclusion JSON Serialization is a crucial topic, primarily if you work with a lot of external requests and different API´s that are changing their contracts from time to time. These should lead to more productivity so that we can implement significant features easier.\nI made a poll on twitter to see which framework is the most used at the moment, but it seems it is pretty close together. My recommendation is to take a look at each package/solution and then use which one fits your needs best.\nThank you for reading and stay curious.\n","permalink":"https://flutter-explained.dev/posts/step-by-step-guide-for-flutter-json-serialization/","summary":"General Serialization Serialization is the process in computer science to convert an object into something that can be saved in a database or be sent via a network request. Today we want to transform a JSON String that we receive from an API and transform it into an instance of an object.\nTo get our Person information as a String, I will work in the following example with the Random User Generator. This can generate random user information and provides us with an API to receive a JSON String.\n","title":"Step-by-Step guide for Flutter JSON Serialization"},{"content":"Navigation is in every application a vital part, and the benefit of Flutter is, that it already contains an excellent routing system built-in. The benefit of a built-in routing system is a huge advantage that we have as flutter developers. As always, we have to know about the hidden traps and understand the tools so that we can decide for the best option for a given use case.\nWith a good routing strategy, you have a lot fewer problems in the future, and it also helps you to reduce boilerplate and maintenance cost in the long run.\nHow does flutter navigation work? In Flutter we have three different options of navigating between screens.\nDirect Navigation with MaterialPageRoute\nStatic Navigation with Route Map\nDynamic Navigation with Generated Routes\nI want to show you all three options on a minimal app that I created.\n1. Direct Navigation with MaterialPage Route The primary navigation that you mostly use in prototyping is usually the direct navigation with MaterialPageRoute. You access an instance of the Navigator and push a new MaterialPageRoute inside. The route creates a new Widget that gets put on top of the navigation stack.\ndart 1 2 3 4 5 6 Navigator.push( context, MaterialPageRoute( builder: (BuildContext context) =\u003e LobbyScreen(), ), ); The MaterialPageRoute is responsible for more than just routing. It also controls the transition and keeps the old route in memory on the stack so that we can route back as soon as we want. For that, we should call Navigator.pop(). This method removes the first Widget from the stack.\n2. Static Navigation with Route Map The second option that we have is the route map, and this is the preferred way if you use a state management tool like, Provider or BloC pattern. You have the option to create a Map with String keys that identifies different WidgetBuilder Methods and take care of the navigation.\ndart 1 2 3 4 5 6 7 8 9 10 return MaterialApp( title: 'Flutter Demo', theme: ThemeData.light(), initialRoute: LoginScreen.route, routes: { LobbyScreen.route: (context) =\u003e LobbyScreen(), LoginScreen.route: (context) =\u003e LoginScreen(), GameScreen.route: (context) =\u003e GameScreen(), }, ); The LobbyScreen.route, LoginScreen.route and GameScreen.route are just the static const String representation of the name of this route. Now you can execute the pushNamed against the Navigator to push the new route on top of the stack.\ndart 1 Navigator.pushNamed(context, LobbyScreen.route); The static “route” is a variable that contains a string that identifies the route to the specific Widgets. Be mindful that if one of your ways contains a slash as a prefix, you have to provide at least one path with a pure “/”. “/” is your primary way. The Widget Builder function, that the map represents for the different routes, getting used to create a MaterialPageRoute inside of the Flutter Framework to navigate to the different Views.\nThe only disadvantage is that you cannot pass a value inside of a route. The dynamic navigation will handle the possibility to pass arguments to the route.\n3. Dynamic Navigation with onGeneratedRoute The third option that I would like to add is the option to create an onGeneratedRoute. The onGeneratedRoute has the advantage that you can create routes and access the passed through arguments.\ndart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 onGenerateRoute: (settings) { switch (settings.name) { case LoginScreen.route: return MaterialPageRoute(builder: (_) =\u003e LoginScreen()); break; case LobbyScreen.route: return MaterialPageRoute(builder: (_) =\u003e LobbyScreen()); break; case GameScreen.route: return MaterialPageRoute(builder: (_) =\u003e GameScreen()); break; default: return MaterialPageRoute(builder: (_) =\u003e LoginScreen()); } } The initial route takes still the responsibility to add the correct route to the stack. The benefit is now, if we call pushNamed, we can use the value of the argument and pass more information into the route. We can initialize the Widget with additional information. So if we push, for example from the Login Screen to the Lobby Screen, we can pass some arguments into the pushNamed method.\ndart 1 2 3 4 5 6 7 onPressed: () { Navigator.pushNamed( context, LobbyScreen.route, arguments: {\"user-msg\": \"Thank you for reading!\"}, ); } As you can see, the push namedMethod takes a parameter called “arguments” which is anything (Object). In our case, we pass a map down that contains a user message.\nIf we change now the onGeneratedRoute that it accepts the argument and passes it down to the LobbyScreen, we pass information into another route with this solution.\nDisadvantage of this solution is that you will lose all types here, so you have to type-check against it later on.\ndart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 onGenerateRoute: (settings) { switch (settings.name) { case LoginScreen.route: return MaterialPageRoute(builder: (_) =\u003e LoginScreen()); break; case LobbyScreen.route: return MaterialPageRoute(builder: (_) =\u003e LobbyScreen( settings.arguments )); break; case GameScreen.route: return MaterialPageRoute(builder: (_) =\u003e GameScreen()); break; default: return MaterialPageRoute(builder: (_) =\u003e LoginScreen()); } }, dart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class LobbyScreen extends StatelessWidget { static const String route = \"lobby-new\"; final Map\u003cString, String\u003e arguments; LobbyScreen(this.arguments); @override Widget build(BuildContext context) { ... Text( arguments[\"user-msg\"], style: GoogleFonts.sawarabiGothic(fontSize: 34.0), textAlign: TextAlign.center, ) ... } } Packages you should be aware of Of course, this is the build-in options for routing and navigation, and there are loads of fabulous packages that could help you optimize your code even further. Some packages that I can recommend are.\nBeamer Another very viable option is Beamer added into the ranks of Flutter favirote you can be sure this package contains quality routing for you.\nFluro Fluro is an excellent addition to the already existing router system, that makes it way more comfortable to use custom transitions between screens.\nAngel Route You worked maybe with an HTTP Server before. Angel Route comes from the Angel HTTP Server. The routing system is in this case isomorphic, and it keeps your code clean and makes it easy to read. Additionally, it handles the pass over of id’s and other information slightly more accessible.\nFlutter Modular The Flutter Modular package is not a simple routing framework. It is a more general project architecture, but it adds many functionalities to the router and uses the standard routing system very smart.\nConclusion Flutters Navigation system is reliable and should help your project in nearly all cases to find the right tooling. There are just a few things that you should keep in mind. But most of the Routing system is already part of the Flutter Framework.\nIf you search further material on Navigation and route I highly recommend the talk of Simon Lightfood about Navigator and Transitions.\nThank you for reading, stay curious and if you have time consider supporting me on Patreon.\n","permalink":"https://flutter-explained.dev/posts/flutter-navigation-everything-you-need-to-know/","summary":"Navigation is in every application a vital part, and the benefit of Flutter is, that it already contains an excellent routing system built-in. The benefit of a built-in routing system is a huge advantage that we have as flutter developers. As always, we have to know about the hidden traps and understand the tools so that we can decide for the best option for a given use case.\nWith a good routing strategy, you have a lot fewer problems in the future, and it also helps you to reduce boilerplate and maintenance cost in the long run.\n","title":"Flutter Navigation – Everything you need to know"},{"content":"To enable flutter web, you have to set up your Flutter CLI properly, and after that, you have to make sure you are on the right channel. Today when I write this post, Flutter web is still in beta, so we have to select a branch that supports beta features.\nbash 1 2 3 4 5 6 7 8 9 \u003e\u003e flutter channel Flutter channels: * master dev * beta stable The master channel is the current tip of development. It contains the newest changes in the framework but it is also vulnerable to breaking changes. So that means in the worst case something is going wrong. The beta channel is a code selection of the flutter team once a month to a branch that contains the newest released features. It is selected and more stable. So if you want to try around, this would be the channel to go.\nFor more information about the channels in Flutter, take a look here.\nbash 1 2 3 4 5 \u003e\u003e flutter channel beta # To download the Flutter SDK execute flutter doctor \u003e\u003e flutter doctor Enable Flutter Web After we set the correct channel and downloaded the new version of flutter, we have to enable the web development model.\nbash 1 2 3 4 5 6 7 \u003e\u003e flutter config --enable-web Setting \"enable-web\" value to \"true\". \u003e\u003e flutter config Settings: enable-web: true Now we are ready to go. Next, we have to create a basic Flutter project. This will create all the relevant folders for us.\nbash 1 \u003e\u003e flutter create ./project-name Flutter create will create all the relevant folders for us. If we open up that project, we should see now the folder “web” inside of the project. The last step is to run the app. So go into the project folder and run flutter devices. We should see now chrome and Web Server as a choice.\nThe last step is to run the app. So go into the project folder and run flutter devices. We should see now chrome and Web Server as a choice.\nbash 1 2 3 4 5 6 7 8 9 10 11 12 cd ./project-name flutter devices # Chrome • chrome • web-javascript • Google Chrome 80.0.3987.87 # Web Server • web-server • web-javascript • Flutter Tools flutter run -d chrome # Should startup your web dev server. After the flutter run -d chrome command, the chrome browser will start up and reveal the Flutter app.\nPerfect, we did it!\nDeploy on GitHub Before we can deploy, we have to create a new repository in GitHub and in order to use it as GitHub pages, it needs to have a specific naming convention.\ntext 1 2 Template: \u003eGitHub-UserName\u003c.github.io Example: md-weber.github.io Now we can create anything that we want in our Flutter app. If we are ready to go we have to build the app.\nbash 1 2 3 flutter build web --release # Compiling lib/main.dart for the Web… 1.6s After that in your project will be a build/web folder. This folder contains all the files that you will need to upload to your GitHub Repository. Open a terminal and switch to the folder and push it into your repository.\nIf you are new to GitHub and Git this Guide could help you.\nbash 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 \u003e\u003e cd ./build/web # The following are the steps that I took, they could vary from project to project. \u003e\u003e git init \u003e\u003e git remote add origin \u003e\u003e git add . \u003e\u003e git commit -m \"Init Flutter web project\" \u003e\u003e git push After the push, GitHub will take care of the rest. It immediately creates for you an environment and pushes your changes to the website. Inside of your GitHub repository, you will find a new Tab called environments. In this tab, you can see how far your deployment process is. Now you can enter find under https://::username::.github.io or my example https://md-weber.github.io/.\nIf you get at that stage a 404 error, please try to add the /index.html to your path and now you should see your very first Flutter Web App. For more information I created a video that explains everything a little bit in more detail.\nThank you for reading, stay curious and if you have time consider supporting me on Patreon.\n","permalink":"https://flutter-explained.dev/posts/setup-a-flutter-web-project-on-github-pages/","summary":"To enable flutter web, you have to set up your Flutter CLI properly, and after that, you have to make sure you are on the right channel. Today when I write this post, Flutter web is still in beta, so we have to select a branch that supports beta features.\nbash 1 2 3 4 5 6 7 8 9 \u0026gt;\u0026gt; flutter channel Flutter channels: * master dev * beta stable The master channel is the current tip of development. It contains the newest changes in the framework but it is also vulnerable to breaking changes. So that means in the worst case something is going wrong. The beta channel is a code selection of the flutter team once a month to a branch that contains the newest released features. It is selected and more stable. So if you want to try around, this would be the channel to go.\n","title":"Setup a Flutter Web Project on GitHub Pages"},{"content":"I searched for a strongly typed language that shows me errors before I am falling for them. Now after one and a half year I can say that I transformed from an Angular 2+ engineer to a Flutter engineer and I even started my own Youtube Channel with the topic FlutterExplained.\nFirst steps I started by creating some smaller prototypes. Without knowing the Dart Language, I wanted to create my first web app, which I did with the help of Chingu. Chingu is a platform where you collaborate with other members of a community to create a new project.\nThe first time I used Flutter I used it in a Web Project and developed the backend with Aqueduct. Aqueduct is a framework in Dart, with that you are able to create a scalable backend. That was a fantastic time, learning Heroku added some CI/CD with Github Actions and was able in two weeks to create a web journal full out of Flutter.\nIt was far from perfect, but jeez I was so proud of it. I wrote articles and showed it in the community, and they liked it very much. That gave me the drive to work harder on my Flutter skills. At the end of 2019, I finally quitted my Freelance contract and started working full time on Flutter.\nStarting with my Flutter Journey I wanted to enhance my Flutter knowledge, I completed a certificate on Udemy from the “The Complete 2020 Flutter Development Bootcamp with Dart”. I was glad that I have done it, just to see all things once more together and understand more of the core concepts.\nAfter that, I tried to replenish my social media channels. My Twitter activity was not existent and my old youtube channel with around 20 subscribers was not worth a lot. Additionally, I had some ideas in my mind that I wanted to realise. Creating a world travel companion and even an electric calculator (which is currently in Alpha). That was the start of my journey.\nFirst, I developed the electrical calculator to see if I can manage to create an app in one week, and well thanks to Flutter I did! There are some improvements that I have to do, but it will be released in the next weeks. Also, I started with my youtube channel and got till now 400 views on a “MediaQuery and LayoutBuilder” Video, which I used to create a better user experience in my app.\nThis is super exciting and I am thrilled that it works like that. This motivates me to improve myself even further so that I can explain everyone, even better the pros and cons of Dart and Flutter Development.\nAdvantages I have never learned that much in such a short amount of time. Also for the videos that I prepare, I have to continually improve myself. Learning to cut videos, add effects, creating better boilerplates, learning flutter details and dart packages. Additionally, my partner and me are working to setup up our own startup which takes time to prepare pitches and talk to investors.\nMy Github Profile explodes thanks to all the commits and if you compare it to 2014 when I draw little pictures in my timeline, it is a dramatic increase.\nFurthermore, I found a way into the flutter community and had the opportunity to talk with people who have the same interest as me. To be part of this new and interactive community is just amazing and the people encourage you to be a better developer in every aspect.\nDownsides Currently, I am living from my hard work of last year, and there are less till no projects for Flutter Development in Germany. So my clear goal to earn money with Flutter is to create my products, services and apps. Also, my Youtube Channel is one of my critical hopes for income. But there are a lot of barriers and if you think you can earn money with BuyMeACoffee … well, think again.\nFuture perspective and Goals for 2020 I still have to learn a lot about BloC pattern, state management and advanced API handling with built_value and built_collection, but that does not keep me away from working further with this great technology.\nI would say there was never a technology stack that cared so much about the needs and desires of their developers. The users love the material design and flexibility. Designers see their creation coming alive in no time. The community seems to be still small but is one of the best groups I have ever worked with. All these things combined make me love Flutter.\nMy goal for this year is to earn a living from Flutter development. The dream would be to go full time on youtube and earn my money as a flutter tutor and speaker. Additionally, I want to publish at least two apps this year.\nThank you for reading so far, please feel free to share your journey with us. I would love to hear more about it.\nThank you for reading, stay curious and if you have time consider supporting me on Patreon.\n","permalink":"https://flutter-explained.dev/posts/how-i-started-with-flutter/","summary":"I searched for a strongly typed language that shows me errors before I am falling for them. Now after one and a half year I can say that I transformed from an Angular 2+ engineer to a Flutter engineer and I even started my own Youtube Channel with the topic FlutterExplained.\nFirst steps I started by creating some smaller prototypes. Without knowing the Dart Language, I wanted to create my first web app, which I did with the help of Chingu. Chingu is a platform where you collaborate with other members of a community to create a new project.\n","title":"How I started with Flutter"},{"content":"First, I want to start by creating a clear picture of what we want to achieve. I work currently on a Scrum Team, we always have to carry around our cards for sprint poker. These cards are old, dirty and very often used from a lot of teams and so I decided to change that with an app, once and for all.\nScrum Poker App If you have never worked in a Scrum Team before, you maybe never heard the term Scrum Poker. To explain the whole idea, would probably be too much for that story, but if you are interested Ravindra Prasad wrote an excellent article about that topic.\nIt is like real poker, but everyone has the same cards. - Max Weber\nVisual guidance For me, it is always helpful in my projects to have visual guidance like a prototype. This prototype can be a drawing on a paper or a fully-fledged prototype. For this article, I created a quick prototype in Adobe XD just to show you how it can look like and to give myself visual support.\nWith that, we have a prototype and now we know what we want to create. Now we are ready for development. First of all, we have to create a new project with Flutter. On the Flutter Website, there are more information on how to set up your environment. I will use for this story Android Studio with the Flutter and Dart plugin.\nRestructure our boilerplate After the setup of the flutter project, let us start with removing all the comments that we do not need. I separate the Home Page from the main file so that we have a better feeling for our application. With that, we bring a bit more order in the project boilerplate. In our main file, this is what should remain.\ndart 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import 'package:flutter/material.dart'; import 'package:flutter_scrum_cards/pages/myHomePage.dart'; void main() =\u003e runApp(MyApp()); class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } In the “myHomePage.dart” you will find the Stateful “MyHomePage” Widget that is initialized with the flutter project.\nAnd the following image represents the folder structure:\nOur HomePage For our first shot, we want to use the existing Scaffold of the HomePage. This contains our scrum cards and a Flutter GridView. The GridView gives us the option to align multiple items in a grid. The count constructor of the GridView provides us, with the out-of-the-box functionality, to create our Grid with Cards.\nFirst, we initialize a variable “Fibonacci” so that we can contain the numbers in an array. If you take a closer look into the children of the count constructor of the GridView you can see the “for Loop”. Is this not great? We can loop inside the children array to map our Fibonacci array to placeholders.\nGreat, the Grid looks already very promising. Did you see how the Placeholder widget is handy in this part? With that in place, we do not have to create anything for the card just yet. However, the result is already evident. The Placeholders help us to structure already our app without actually implementing something.\nThe Cards Now that we have the basic structure in place, we have to think about how we want to display our Cards. Thankfully Flutter provides already something for us. The Card Widget will help us to create excellent visualization of the cards with Text inserted. Because the cards will not change, we can create a stateless widget for it with an icon or a number. For now, it will live in the “MyHomePage”.\nGestures Now it is time to control our behaviour of the app. When we tap a card, it should remove the widgets from the tree and replace it with a single card widget. That, however, changes the state of the “MyHomePage” Widget.\nTo achieve that tap behaviour, we first have to surround our Card element with a GestureController. After that, we have to specify the onTap event inside of the card.\nThis will now print every click on a card in a separate line in the console.\nDowntime Alright, we made it very far already. So let’s take a break and recap shortly, what we created already.\na Design for our Scrum Card App\na HomePage\na ScrumCard widget\nGestures and tapping event\nThe next thing that we need to do is to change the state of our app, after a tap. Whenever a card is tapped we want to replace the Body from the HomePage with a Big ScrumCard Widget.\nNow comes the tough part so. Therefore make yourself ready, take a deep breath and then let’s get into it!\nState Management There are two different kinds of Widgets in Flutter.\nStateless Widgets\nStateful Widgets\nThe stateless widget is a widget that will always be shown according to its initial values. During its lifetime the initial values can not change. The stateful widget, on the other hand, contains a real state and if you change the state the widget will be re-rendered. If you want to read more about the different types of widgets feel free to take a look at the article by Deepak K.\nNow we have to first time handle the state of our widgets. When we click the button the state of the “Grid Widget” should change to a big “Card Widget”. This tells us that we have at least two different states in our app. To keep track of these states we have to change our current “Stateless” Widget to a “Stateful” Widget. The easiest way is to click on Stateless Widget and use the IDE function to change the Stateless Widget to a Stateful Widget.\nBecause the new Widget is now stateful, we can change its value and the “build” method can react to these different states.\nWe want to track the information of the Icon that we want to show or the Text that is visible on the card so we need that to a state. I call that variables “singleCardText” and “singleCardIcon”. Additionally, I want to have a boolean that knows if I have to show the Main Page with all Cards or just the Single Big Card.\nBe careful at that point, I made here a big mistake and put all these variables in the build method. The build method gets called multiple times and whenever it gets called it overwrites the values again. Of course, that sounds trivial but cost me 1 hour of my lifetime.\nThe Exchange Now we want to swap the widgets based on the “isHomePage” value. Therefore, we can use one of Flutter skills. We surround our GridView.count constructor with a ternary operator. That checks our isHomePage and add the respective Widget to the Container.\nIf you get confused by the “?” and the “:” in the code I can recommend you to read an article about “Ternary Operator” from Deven Joshi. With that in place, we have the opportunity to change the “isHomePage” to false and it would show us only the Padding (and whatever is there inside) or we keep it on true, and it will show us the GridView. Therefore we need the “setState” method. It will allow us very easy to change the current state of the widget.\nGreat so far. Now instead of the tap where we just print something in the console, we want to execute the “switchToCard” method. But how? The method has to live in the _HomePageState and the ScrumCard has no access to that state? Alright then, let me explain it to you because there is a fairly simple solution to that problem. We just pass our function into the ScrumCard Widget. And whenever the user taps now on the card we call that method and “notify” our parent widget.\nIf you take a brief look into the code snippets you can see that the ScrumCard calls the notifyParent method, which in fact is the switchToCard method. This should help us now to transform from a grid with multiple scrum cards, to a single big one and Vice Versa. Now there is only one step left, we have to create a beautiful Card UI that will be generated when the isHomePage is false.\nAs you most likely already discovered I added here another function for notifyParent so that we can swap back to the HomePage.\nNow the switch of card and grid should work already. To improve our app even more we can use the “AnimatedSwitcher”. I found this amazing video from the flutter team and that is a perfect use case. The AnimatedSwitcher, as you maybe have already guessed, helps us to swap two widgets with each other. It adds a smooth transition between these two and this looks much more friendly. You just have to put your ternary operator in between as a child and give it a Duration how long the transition should take.\nOk, so let’s run our simulator or emulator and take a look how the app looks now.\nConclusion and What’s next This is now an app that already solves one important problem in software engineering. From now on I do not have any more to carry real cards from one room to another. Never again I will have to grab old smelly cards and show them to my Product Owner. We do not want to know which liquids touched those filthy cards…\nThis is of course just the beginning. With the knowledge that we got during this session, we can do much more. This app shows how easy it is with flutter to create a nice fully functional app.\nNow it is your turn. My challenge for you till my next article is, to create this app or fork my repository from GitHub and extend this app by a small additional functionality. To give you some examples that you could add,\nMake it possible to change from Fibonacci numbers to other Scrum Poker numbers\nCreate a history of the selected cards\nMake a custom Animation between the transitions\nAnd if you are finished spread the word and let everyone know how cool Flutter and our community is! I am already curious to see all the beautiful results. If you have any feedback let me know and if you are interested in other cool articles, feel free to follow me on Twitter or take a look into my GitHub Repository.\nThank you for reading, stay curious and if you have time consider supporting me on Patreon.\n","permalink":"https://flutter-explained.dev/posts/flutter-project-scrum-poker-app/","summary":"First, I want to start by creating a clear picture of what we want to achieve. I work currently on a Scrum Team, we always have to carry around our cards for sprint poker. These cards are old, dirty and very often used from a lot of teams and so I decided to change that with an app, once and for all.\nScrum Poker App If you have never worked in a Scrum Team before, you maybe never heard the term Scrum Poker. To explain the whole idea, would probably be too much for that story, but if you are interested Ravindra Prasad wrote an excellent article about that topic.\n","title":"Flutter Project - Scrum Poker App"},{"content":"Pen \u0026 Paper: My best friends before starting to code To be honest with you, I had no idea what I should code at first! So I started to google and figured out how I should begin and process my task to be successful. One of the best articles that I found was Learning by Cloning: How to Decompose the Problem, from Jim Medlock. After I read it, I tried to follow the instruction in step three and decompose my original website.\nAt first, I opened the original website and tried to understand the structure of the website. Unfortunately, the design of the website has been changed since I created this blog but I hope you can see the design in the image below as well. I start to markup the site and break it down into small components and pieces according to the content and the responsibility of each piece. This is how it looks like:\nEach piece has an individual task. 1. Navbar is responsible for the menu and the navigation between main pages of the website 2. Mega menu is also a menu component, which is much more complicated. It extended dropdown and contains different categories. 3. Wrapper for content represents the main content of the page, and this consists of four sub-components. 4. Footer contains social media links, copyright and some other information.\nAfter I finished analysing the website, I grabbed a pen and paper. This is the easiest way for me to bring everything on paper, which I’m going to code later. I generally create a sketch of the website with the boxes that I created in my last step. Now it’s time to think about HTML tags, that I’m going to use in my code.\nBelow you can see my sketch on the paper with components and their possible HTML tags.\nChallenges while creating my first sketch for clone a website As soon as I had a clear plan and knew what I should do and where I should start, everything is much easier and make more sense.\n“Before wasting time and start coding without any plan, take a moment to understand the problem. After that, create a plan, and the last part is starting to code.”\nI think the essential part of every programming problem or in this case cloning a website is at first to understand the problem. As soon as we understand and analyse the problem, we have done more than 50% of the task. Also, it will help us to solve the rest much more straightforward.\n“Stop trying to be a perfectionist \u0026 Believe in your sketch and your solution”\nAfter my first sketch, I started to improve it again and again, which was more time-consuming rather than helpful. I forgot the purpose of my drawing, which was to have a rough plan where and how I should start. I needed my sketch to consider it as the base structure of my code and not to have a beautiful and best draft for the website. So before you make the same mistake as I, jump to the next step. You will always have the chance to make it better or even change your structure if it’s necessary.\nImplement the sketch into code The requirement for my Chingu project was to clone the website using HTML, CSS and JavaScript. Therefore, I opened my IDE and created an HTML5 boilerplate and start to code. But if you want to use any other technical stack or framework, don’t wait longer. Create your boilerplate and kick off your project as soon as possible.\nTo implement my sketch into code, I started at first to bring each block in my draft as a div in my code. It means at the end I had four divs, and I marked them with different class names. So I prevent to forget what the purpose of each block should be.\nhtml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 \u003cdiv class=\"menu-container\"\u003e \u003cnav class=\"navbar\"\u003e\u003c/nav\u003e \u003c/div\u003e \u003cdiv class=\"dropdown-navbar\"\u003e\u003c/div\u003e \u003cdiv class=\"wrapper\"\u003e \u003csection class=\"header-section\"\u003e\u003c/section\u003e \u003csection class=\"general-text\"\u003e\u003c/section\u003e \u003csection class=\"first-section\"\u003e\u003c/section\u003e \u003csection class=\"second-section\"\u003e\u003c/section\u003e \u003c/div\u003e \u003cdiv class=\"footer\"\u003e \u003cul class=\"horizontal-list\"\u003e\u003c/ul\u003e \u003cdiv class=\"social-media-list\"\u003e\u003c/div\u003e \u003cp class=\"footer-text\"\u003e\u003c/p\u003e \u003cp class=\"footer-text\"\u003e\u003c/p\u003e \u003c/div\u003e After that, I had a basement for my code, and I could dig more in each block to expand it. I started with each div to code in details and complete it as same as in the original website.\nWrapping it up Cloning a website sounds pretty straightforward. But it can be tough and frustrating if you don’t have any plan for how you want to start and implement it.\nSteps to create a website sketch:\nOpen the original website - Analyse the website base on structure and task of each part and break it down to small pieces - Create a sketch of a website on a paper - Decide for HTML tags - Don’t try to improve your sketch over and over - Implement your sketch into code - These steps helped me to go through this challenge and complete it successfully. Hopefully, it will also help you and make this challenge for you easier. If you have any other idea and would like to share them with me, I would be more than happy to hear from you.\nHere you can have a look at the original website. This is the live version of my cloned website and if you like to know more about my source code, check it here on my GitHub.\nThank you for reading, stay curious and if you have time consider supporting me on Patreon.\n","permalink":"https://flutter-explained.dev/posts/clone-a-website-from-scratch/","summary":"Pen \u0026amp; Paper: My best friends before starting to code To be honest with you, I had no idea what I should code at first! So I started to google and figured out how I should begin and process my task to be successful. One of the best articles that I found was Learning by Cloning: How to Decompose the Problem, from Jim Medlock. After I read it, I tried to follow the instruction in step three and decompose my original website.\n","title":"Clone a Website From Scratch"},{"content":"GitHub Actions — Can I eat that? The short answer is no, but if you want to build, pack and deploy your app, it is maybe something for you. Github Actions is the CI / CD project from GitHub. The CI / CD allows us to set up workflows for different scenarios of our app. It gives us the possibility to build our app, test our application and also to publish at the end our APK. The best thing is that you dont even have to leave your GitHub page.\nSo why should I use GitHub’s new service compared to all the others like Travis CI, Bitbucket or codemagic? Well on the first glance the pricing model is ridiculously cheap compared to the competitors. All public repositories are free for this service (GitHub announce that they love OpenSource). And private repositories can start with a free plan of 2000 build minutes a month. Additionally it allows other users to create their own actions that they can share with other users.\nGitHub Actions in Action So let’s get into it, by integrating GitHub Actions with our flutter repository. As soon as you open your git repo you will find a new Tab called “Actions”. This brings you to a page where you can find all your created workflows and if they where successful or not.\nWhen you navigate into the actions tab the first time, you will find a message that informs you that it has already scanned your repository and gives you a suggestion. This suggestion would create us a basic workflow that fits our current project. That is quite handy and allows us to implement the first steps really fast. In our Flutter project it will recommend us the typical dart installation path. But because we want to install a flutter application we have to do something different here.\nWe have to create a custom workflow to achieve a build with flutter. We could skip the initialization of the workflow and write our CI / CD code directly on the website of GitHub. This would be much harder and therefore I decided to do that in our repository with the IDE of our choice. Therefore, we jump right into our IDE and create a new folder “.github” in our project root for our GitHub Actions. The “.github” folder contains all our files that represents a workflow in our GitHub Actions. For example, we can create our first main.yaml.\nyaml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 name: CI on: pull_request: branches: - development - master jobs: test: name: Flutter Tests runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - uses: actions/setup-java@v1 with: java-version: \"12.x\" - uses: subosito/flutter-action@v1 with: flutter-version: \"1.7.8+hotfix.4\" - run: flutter doctor - run: flutter pub get - run: flutter test build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - name: Run a one-line script run: echo Hello, world! - name: Run a multi-line script run: | echo Add other actions to build, echo test, and deploy your project. Line 1: We declare our Action name in the file above we call it CI. The name will be represented later on the GitHub Page to indicate if this workflow failed or passed. On line 3–7, we describe the triggers for that workflow. In the our example, the workflow will be executed whenever we create a pull request to master or development branch.\nFrom line 9 to 27 we declare the Jobs. Our first job has the name “Flutter Tests”. Which is again a collection of Job, and every Job contains one or more steps. It is good to know that every Job has its own virtual environment, which let it not leak information to another job. Additionally, it is essential to know that jobs can work in parallel or could be dependent on each other. For example, component tests and unit tests could run in parallel, but both are dependent on the build. So if the build fails, the tests will not run, but if one of the checks fails, the other one will continue.\nIn-Line 19–21, we use an open-source action that Alif Rachmawadi created for us, to install our flutter dependency. These open-source actions show a very great thing of GitHub Actions. Every user can create their Actions and publish them for everyone.\nNow, after we installed our flutter dependency, it is time to let in the last three commands let run our flutter doctor, flutter pub get and flutter test. Moreover, that is it, we created our first pipeline, and after we create a pull request to development or master the test is running.\nBenefits of GitHub Actions Another benefit is that it is possible to protect branches. Therefore only Pull Requests with a green workflow are elligable to be merged. You can find that option in “settings” branches, and there you select a branch that you want to protect.\nSo GitHub indicates us now very clear that we should not merge it and other contributors are not even allowed to merge without a green flag. That supports our code quality and also our time management.\nConclusion We created our very first GitHub Actions and had the opportunity to test our flutter application. For us Flutter developers, it is not as convenient as codemagic that creates the whole pipeline in seconds and is ready to use from development to publishing. However, if you take the time and effort to create it in GitHub, you can get a very cheap plan for your build pipeline.\nIn my opinion, we have here an excellent tool for building our applications and see if the tests are green before we work further. Also for Community projects this seems like a very convenient way to work. However, I also could find one small downside. Currently, it seems not possible to cache some information, and with that, the build time for the flutter project boilerplate was around 1 min 38 seconds. If the Flutter SDK could be cached, I think it would come down to maybe ~40 seconds.\nDid you set up your first GitHub Actions? What do you think has it a chance to be one of the most used building pipelines in the world? Let me know in the comments. If you want to see how the flutter pipeline works in action, feel free to take a peek in my current project repository\nThank you for reading, stay curious and if you have time consider supporting me on Patreon.\n","permalink":"https://flutter-explained.dev/posts/github-actions-for-a-flutter-developer/","summary":"GitHub Actions — Can I eat that? The short answer is no, but if you want to build, pack and deploy your app, it is maybe something for you. Github Actions is the CI / CD project from GitHub. The CI / CD allows us to set up workflows for different scenarios of our app. It gives us the possibility to build our app, test our application and also to publish at the end our APK. The best thing is that you dont even have to leave your GitHub page.\n","title":"GitHub Actions - For a Flutter Developer"},{"content":"I am coming from a Front End development background, and it’s always more comfortable for me to break down my applications from top to down. That usually means I first start to implement the basics in visualization and then come slowly down to the nasty backend world and save my stuff finally on a database.\nOrganization of my project This is one of my first experiences with my own real project. Therefore I needed to come up with a good structure for my GitHub Repository. I knew I will have a backend, aka “server”, and a web “client”. So I created the projects inside of the subfolders “server” and “client” (Creative I know).\nBesides of Server and Client you will find also a “scripts” folder. Here I always collect powershell scripts that I do not want to always execute myself, like setup my development environment or deploy a database.\nThe readme.md contains information about my project. It explains how to setup my project and other useful things around my project. I found a very good template from Eric Zumwalt and if you are interested you can find it here.\nThe .gitignore file is important for git to know which files I do not want to upload. Like for example the .idea folder that takes care of the settings of my Integrated Development Environment (IDE).\nThe Flutter Web Client Now that the project structure is ready, I started to create the client for my project. I followed the guidance of Ayush Shekhar. He wrote, about how to create a flutter web project in a couple of minutes. So let’s go and set up the environment for client and server. The flutter web environment was not as comfortable as I expected. I did the following steps.\nBe aware that I assume in that post that you already installed the Flutter and Dart SDK. If you have not done that yet please take a look at flutter.dev.\nStep 1. Activate a global package “webdev” To activate the webdev package we have to run following code in the command line.\nbash 1 flutter packages pub global activate webdev Step 2. Activate a global package “webdev” The second step sounds fairly simple. Unfortunately, it took me a while to discover that the Flutter Web App is in Intellij Idea (My IDE for that project) in Dart Projects.\nBut easy as this, I created a “client” folder in my project with a flutter web boilerplate. After the creation of the project, it has been three commands to run my very first flutter web app.\nbash 1 2 3 pub get webdev serve Requirement Analysis The project structure is clear, and we have done our first steps in a flutter app for the web. In this section, I want to split my work into different work packages and show you how I proceeded to create the client for the project. Chingu was already so helpful and made a basic design for us that I wanted to replicate\nWhenever you read or hear about flutter, you will hear the word “Widget”. It describes every component in a flutter. So we can say everything we see in Flutter is a widget. Basic Text, a Button or even compositions like a ListView are widgets. With that in mind, I started to create a mind map of different reusable widgets.\nWith that Widget Map in front of me, I started to create the application. In the beginning, I started to write everything from top-down in every widget and as soon as I found out that something is clearly not part of the main widget I started to tear it out and fit it as good as possible to the Widget Map above. For example, a Note List Widget will contain multiple notes. A note consists of a card with a header, content and footer section and so on.\nWorkflow in Flutter I don’t have a lot of knowledge about Flutter, so I just started to write the widgets and found it very satisfying how the compiler and all development tools screamed at me as soon as they had a problem with my coding. I come from an Angular and Typescript background in which the compiler is not so reliable and descriptive.\nDart and Flutter are entirely different. First, the workflow. You can not just change something in the browser. Because other than Angular or React, you are not dealing with HTML \u0026 CSS in the inspector. You deal with something that Flutter calls glass pane. The HTML looks as following.\nAnd yes it is still XML, and maybe it even translates somewhere in HTML, but at the end, you are not able to use the web inspector anymore. That is very interesting.\nOn the benefits site, all changes in Styling are now strongly typed. You are not able to make any mistakes by writing something wrong, because Flutter will not compile it. The documentation is some of the best I’ve ever seen in my development live. Let me give you a small example of how to change the style of a text element in Flutter.\ndart 1 Text(\"Hello World!\"), Here you see the “Text” Widget to create a new Widget. We have to pass the string that we want to display into the constructor. So if we’re going to change the style of that Text, we add to the constructor a style attribute. Which is again a TextStyle Widget. The TextStyle itself has several parameters, like color and the fontSize.\ndart 1 2 3 4 5 6 7 child: Text( \"Hello World!\", style: TextStyle( color: Colors.white, fontSize: 42.0, ), ), If you do something wrong, the development tools will show you immediately. The feedback loop is tiny, and you will know if you make mistakes. There is also a very good article about TextFields from Deven Joshi if you are interested in reading more about them.\nConclusion So after a while of writing new code, I finalized my prototype with absolutely no backend support.\nGreat! Everything works well and nothing looks like the web, it seems more like a mobile application. For example, the navigation in forms with the tab key is not working yet. On first glance, it looks pretty weird, and it is, but I know that the Flutter Team and the Flutter community working hard at that to make the web more future proof.\nAn exciting thing that I found during the development phase was that when the browser got too small. There was a warning massage in chrome that indicates me that the text was not readable or that a list did not fit anymore. That means I could directly see where the responsive design is not correct. This can be very handy in the future if you think about Mobile-first approaches.\nSo this is it, we managed the beginning of my Flutter Digital Journal together. Now with the basics in place, we can begin with coding my way to the end of the challenge. If you are interested, please feel free to check out my repository or the current release of the Flutter Digital Journal.\nThanks for reading, enjoy your Flutter Journey and if you have a moment consider supporting me on Patreon!\n","permalink":"https://flutter-explained.dev/posts/flutter-journal-app-full-project-with-chingu/","summary":"I am coming from a Front End development background, and it’s always more comfortable for me to break down my applications from top to down. That usually means I first start to implement the basics in visualization and then come slowly down to the nasty backend world and save my stuff finally on a database.\nOrganization of my project This is one of my first experiences with my own real project. Therefore I needed to come up with a good structure for my GitHub Repository. I knew I will have a backend, aka “server”, and a web “client”. So I created the projects inside of the subfolders “server” and “client” (Creative I know).\n","title":"Flutter Journal App - Full Project with Chingu"},{"content":"keywords:\nFlutter Dart Personal Development tags: Flutter Dart Aqueduct After six months of travel, we decided to stay in New Zealand, and I got some work as a software engineer very quickly. The work there is good with a lot of friendly people around me. But currently, I am not happy anymore with Angular as a technology stack. But to do private projects is quite hard, and somehow the motivation is missing that pushes you to completion until my girlfriend had an excellent idea.\nThe Idea: Real life Projects My girlfriend is currently changing her career from a sales accountant to a software developer. In her learning process, she found an exciting offer called Chingu. Chingu means so much as “Friend” in Korean. I am a full-stack software developer myself for eight years, so I first started to ignore the offer. Because what they offer is to learn development and getting better in coding with people who also want to get better.\nAfter her first “voyage” she was so happy and told me every day about her new adventures, that I also decided to take a look and participate. So I decided to sign myself up for the Voyage 11 of Chingu to see how it is and to see what a long term developer can take out of the experience. First, I looked on the medium page of Chingu and was pretty exciting to see how much effort people did to improve themselves with real-world examples and projects.\nAfter she convinced me that I could bring up some spare time to join Chingu and can also implement the Solo projects\nthat they want to prepare before you even can join, I signed up for my very first voyage. Besides the usual questions like your name and gender, you also get the item which role you want to take in your team and which Tier level you think you are. There are three Tiers in Chingu.\nTier 1: HTML \u0026 Basic JavaScript In this tier, you will work on a copy of a website that you can see online, this can be quite challenging, especially if you do not know about frameworks and libraries that you can use.\nTier 2: Intermediate Algorithms and Front End Projects Here you will usually also build a website with an API connection where you try to get data from a provider and use them to visualize them. Also, you are familiar with one framework like Angular, React or Vue.js.\nTier 3: Full Stack Developer In Tier 3, you will find everyone that can participate in more significant projects and have knowledge about backend services, API and a good understanding of how to create a webpage.\nAlright then, Tier 3 it is. I am already long term developer and working with an algorithm for a long time. Therefore let’s go and write some code. The invite for the Pre-Work challenge arrived three days ago, and I am highly motivated and looking forward to seeing how it works.\nThe prework challenge is a digital journal, where people can enter in a basic form the body of the note and ahead of the record. Additionally, it should be possible to log in. Also, there are the requirements to have no errors in the log file and to write the API for it. In the end, you should deploy API and Client to Heroku or another provider of your choice. The choice of the Framework is completely free.\nLet the challenge begin After reading the Chingu Handbook that explains what you have to do and what your tasks are I started right away (yes I know there is plenty of time, but I was excited and super motivated).\nTherefore I forked the Repository and started working on it.\nFirst, I decided on a framework, and because I currently want to learn Dart and Flutter (since Google.IO 2019, I got hooked), I settled for them. I mean, where is the challenge if you take something that is already released?\nTherefore I decided to take a look at the Flutter Web Framework. Perfect thus, the Client Framework is settled and now something for the backend. I do not like to have in a project multiple languages, and I love it if the backend is the same language as the client. For example, I want to have an Angular app with a Node backend. Or even a C# Application with a C# API. Therefore I decided to use in my case Aqueduct (I would recommend today Conduit), which is a server framework in Dart.\nAre the framework choices the best solution for my problem? No idea, but if I wanted to have the best fit, I could go into my company and not challenge myself in a Chingu project.\nAfter the selection, there was a big road of joy and development in front of me, and I started my journey by writing several hours code, reading the documentation and learned a hell more about Dart, Flutter and Aqueduct.\nBut this should be enough for this story, and I will keep you up to date how’s it going in the next couple of articles.\nIf you want to join me on this first voyage of mine, check out my repository\nand if you see issues, please report them.\nWow, you made it this far, this is my first article, so I would be grateful for every feedback that you can give me. Thanks for reading and have a wonderful time!\nThank you for reading, stay curious and if you have time consider supporting me on Patreon.\n","permalink":"https://flutter-explained.dev/posts/i-go-on-a-chingu-journey-with-flutter-dart-and-aqueduct/","summary":"keywords:\nFlutter Dart Personal Development tags: Flutter Dart Aqueduct After six months of travel, we decided to stay in New Zealand, and I got some work as a software engineer very quickly. The work there is good with a lot of friendly people around me. But currently, I am not happy anymore with Angular as a technology stack. But to do private projects is quite hard, and somehow the motivation is missing that pushes you to completion until my girlfriend had an excellent idea.\n","title":"I go on a Chingu Journey, with Flutter, Dart and Aqueduct"},{"content":"In January 2018 I started to realize my dream and learn how to code with Udacity. I took a six-month Intro to Programming course and started to learn HTML, CSS, JavaScript and Python. At this time I had my full-time job in Germany in Sales with my background of M.Sc in Industrial Engineering.\nThat was a tough time for me to focus on learning every day after eight hours of work. Even if on weekends, I had to spend time to learn and submit my exercises and projects. I was never in such a short time so often frustrated and stuck in problems, like this six months. But I was never so amazed and motivated to learn something, that I couldn’t give it up. After six hard months, I managed to get my first certificate in programming from Udacity.\nAfter one year of doing many tutorials, code challenges and learning and building projects, I came to New Zealand for Work and Holiday. I was pretty sure that I can find a Junior Developer position or at least an Internship position as a Developer. After sending many job applications and went to meetups, I could finally get an internship position as a Software Engineer in a startup company for three months.\nThat was an amazing and huge opportunity for me to get the foot inside of software development world. After a couple of weeks, I realized that I will definitely not have an easy time there. I think the biggest challenge for me was that I was alone as a junior developer between senior developers. Pair programming was not welcome in the company, and they could not understand my needs and my problems. Therefore, I didn’t feel like I belong, feeling more like an outlier.\nWhat I missed during my software developer internship? For sure, I learned very much in just three months about software development, but I had always a lack! As a junior software developer, I missed someone who understands me, someone who is willing to support me. I wanted to be more efficient in my working time and do more significant progress.\nDuring these three months, I looked for a solution until I read about Chingu on medium! As soon as I read “Learn how to be a team developer \u0026 Join a motivated community”, I immediately applied for it. A couple of weeks later was accepted onto the program and got an email with an official invitation to Voyage 10.\nIn the last two weeks of my internship, I worked on my Chingu Pre-Work Solo Project and submitted successfully. So that I could directly start with my Voyage Project after my Internship.\nWhat is Chingu and how does it help me to improve my developer skills? “Chingu is a global collaboration platform that connects motivated learners who have shared goals to learn, help, and build together.”\nChingu creates teams of developers just like in the real world with a similar capability together. Chingu motivates and encourages teams to build a project together. I was in a group of three developers. We worked on our project from New Zealand, Japan and Holland! We all had the same goal and that was LEARN and BUILD together, help and learn from each other and …\nPhoto by Jordan Whitfield on Unsplash\nAt the beginning of our project, after our first team meeting in Hangouts, we planned our development procedure with the fundamental information which was provided in Chingu Handbook. Like every company with the agile methodology and scrum, we planed our milestones, sprints, sprint review and retrospective and of course our daily stand-ups.\nThis was just the perfect chance to work in a team with people who have the same target as me. In our daily stand up we spoke about what we did, what we are going to do as next and if we stuck in any problem and need help so that we could arrange a pair programming section to solve the issues.\nWhat did I learn during my Chingu Voyage 10? Each Voyage is split into three different Tiers, base on the project’s complexity. For all of my team was clear to go on with a Tier one project. We started to work step by step through the Chingu Handbook. We learned a bunch of things in these six weeks, as it would most likely not possible to do it alone in a solo project.\nSome examples for me were like:\nDeep understanding of the agile methodology\nLearn GitHub, set up a repository, git branches, create PR and make code review\nHow to work in a remote team, manage and deal with different people and improve our coding skills\nLearn Angular and TypeScript, suggest each other good resources for learning such as Angular Tutorial with Maximilian Schwarzmüller\nCreate a product backlog with ZenHub\nCreate Angular Boilerplate, pick up tasks on ZenHub and start to code\nBe active in Chingu community, ask and answer questions in Discord\nLearn Heroku and deploy our MVP\nPhoto by Mahtab Tadayon\nConclusion Finally, I would like to tell you the main reasons, why I believe Chingu is very helpful for all and especially for junior developers:\nYou will see and understand how software projects and real developer team works.\nFor each Voyage, developers are provided with all essential information, which is necessary for a successful project. You can directly get the first benefit out of that and learn a bunch of stuff.\nChingu community is full of developers, who are eager to work, to learn and help other developers. They have all the same goal and it’s very important, to stay motivated and know that you are not alone in this tough journey.\nIn the end, I would like just say thanks to Chingu team for this great opportunity and that they make it possible for us to get the best experience to be part of an amazing development team and community.\nYou can check out the live version of our Chingu project and know more about the project in our source code.\n","permalink":"https://flutter-explained.dev/posts/six-weeks-with-chingu-to-feel-like-a-software-developer/","summary":"In January 2018 I started to realize my dream and learn how to code with Udacity. I took a six-month Intro to Programming course and started to learn HTML, CSS, JavaScript and Python. At this time I had my full-time job in Germany in Sales with my background of M.Sc in Industrial Engineering.\nThat was a tough time for me to focus on learning every day after eight hours of work. Even if on weekends, I had to spend time to learn and submit my exercises and projects. I was never in such a short time so often frustrated and stuck in problems, like this six months. But I was never so amazed and motivated to learn something, that I couldn’t give it up. After six hard months, I managed to get my first certificate in programming from Udacity.\n","title":"Six Weeks with Chingu to feel like a Software Developer"}]