Sunday, April 12, 2020

April 6 - 12 Skills Challenge


New stuff learned for the days April 6 to 12, 2020. Quarantine days!


  • Single-SPA
  • Google Cloud Storage
  • Google Kubernetes
  • Google App Engine


Since I've been vacant for quite sometime now, I went to apply for a job last week and given a test challenge for the post. The challenge was to use Single-SPA javascript library. Basically, it's a library that can let you develop an app as microservices and you can use different JS framework or libraries such as VueJS, ReactJS, Vanilla or Angular.

It was cool, I thought it would be easy for me or just a walk in park, by reading the documents I was able to grasp the concept and how everything works. The goal for the challenge test was to learn how to develop an app with Single-SPA and its deployment process.

What I did was a single app approach but still implemented the split application somehow. I have a root config for the app that will load an application when user navigates to a given route. Though, the idea was to split the app by section, like footer, header, sidebar, styling and so on. The idea is to separate each section to have their own repo, which is very convenient for a large team. It's also ideal for migrating one section to another library without affecting the entire app.

Google Cloud Platform.

As I completed doing the basic setup of Single-SPA, it was time to deploy and test it on live site. Using the GCP for the deployment, I now learned how to use its Kubernetes product. And also learned how to use the built docker image, push to Google Container Registry and use it for cluster.

The flow will be

docker build .  ----> build the image
docker tag  --> tag the newly build
docker push  --> push to registry

docker tag <tag_name> <registry_name>/PROJECT_ID/<image_name>

[HOSTNAME] is listed under Location in the console.
It's one of four options: gcr.io, us.gcr.io, eu.gcr.io, or asia.gcr.io.
docker tag ceabfea5e26a gcr.io/boreal-totality-/single_spa_image:test
docker push [HOSTNAME]/[PROJECT-ID]/[IMAGE]
docker push gcr.io/boreal-totality-273505/single_spa_image


And for the last day of the week, April 12, I mostly spent time on Google App Engine and setup my local Kubernetes using minikube and kubectl. With Google App Engine, I just tried to setup a Laravel app. With Laravel requirements, I was able to use SQL service of GCP and have it connect to my Laravel app.

Flutter

My simple test application has been in long hiatus and finally, I was able to revisit and make it work again using the updated version. So I might be able to work on it next week. Btw, I've encountered an error with Flutter http module, I keep getting a 401 response with my login flow. With quick search for help, I found out that the post should have a headers with Content-Type of json

My code snippet would be like this now,

var response = await client.post('$login_path',
                            headers: {"Content-Type": "application/json"},
                            body: json.encode(form));

That's it for now.

StayHome StaySafe


Saturday, October 27, 2018

Note: Making React Native work

After moving my workspace from Windows 7 to Windows 10, I have so many things to do to make my small React Native (RN) project to run again.

I managed to make it run again by following RN's getting started  procedure. First test was to make the RN sample work.

Great! Everything works fine, I guess.

Problem started to come out as I started importing my files to the new project (react-native init AwesomeProject).  From the getting started page of RN, it says that you need to activate Android's building SDK tools version 26.0.3 but it actually throws errors. So, I activated both 28, 27 and 26 Android SDK Platforms. I would also test if I can deactivate the two and use the latest only which is 28. After that, I've encountered a lot of issues with the packages I'm using like react-redux, native-base,  redux-persist and others since I have to run npm install at least twice to successfully install the package.

When I finally make it run on android emulator, I noticed that native base's icons are not showing up. It'll show the [X] placeholder. Of course I forgot to follow the instruction that says run "react-native link" as discussed here. After making the assets linked, Another error spits out from the emulator which is Unable to load script from assets index.android.bundle on windows.  Good thing someone posted same question at StackOverflow and the solution is which I quoted below.

I've encountered the same issue while following the React Native tutorial (developing on Linux and targeting Android).
This issue helped me resolve the problem in following steps.
  1. (in project directory) mkdir android/app/src/main/assets
  1. react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res
  1. react-native run-android
You can automate the above steps by placing them in scripts part of package.json like this:
"android-linux": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res && react-native run-android"Then you can just execute npm run android-linux from your command line every time.
For now, my testing app is already working and I can continue from where I stopped before and on my new unit.

Wednesday, October 24, 2018

It's a hard Nuxt life

That following issues are needs to be address while

  • Running Nuxt with Node experiences crashes once in a while or very frequent
  • Make a static version (Nuxt generated version) of the live version (running on NodeJS)
  • Nuxt generated static html files for pages are not complete. Missing end tags for body and html.
DAY 1.

When I did the migration, my initial results that css files are not included at the production. Running at the development, all pages are working right with no hiccups. So weird? Well, I guess I'm really new at this stack.

My initial solution is take them piece by piece and of course get rid of jQuery. So many parts that uses jQuery and it's painful and it would take a lot of time, but for me, I think it's worth it. But we need it right away.

As they say, if there's a will there a way. 

Day 2

At first we were testing the results for SEO stuff at Google Webmasters' Fetch / Fetch and Render, every page is being cut off. For hours we thought it's coming from the CSS files. Take it off one by one including the plugins. Still the same!

Someone said there's an issue with asyncData method if using the static version of Nuxt. So, I created a simple test. Plain and simple pages, one page make a request from and API endpoint. asyncData not an issue.


Day 3

Found out that generated files are already cut-off or doesn't have a proper end tags for body and html. Problem could be during the compilation of js, css and everything. I update the Webpack version from 3 to 4. Ooops, there'a a lot of dependency issues. And so, Nuxt used was outdated so that could be one of the reasons. Maybe, just maybe. 

With a new create-nuxt-app, I started to import piece by piece. Suspected plugins are all working. What's happening? Generated pages are not being cut-off. It was going well. Then I completely migrated everything and did the "npm run dev". It's working!. I immediately ran "npm run generate" and deployed to my dev site. Damn! It has no styling. At least html are terminated pages. 

First solution. Use an external css. Now, it really works. It doesn't end there of course. I'm still having issues with the external css, font's were not loaded properly. So, I added an .htaccess file to allow it.

<FilesMatch "\.(ttf|otf|eot|woff)$">
    <IfModule mod_headers.c>
        SetEnvIf Origin "http(s)?://(www\.)?(anotherwebsite.com|cdn.anotherwebsite.com|blahblah.anotherwebsite.com)$" AccessControlAllowOrigin=$0
        Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin
    </IfModule>
</FilesMatch>
Day 4

It's workable but seems to be tedious, when I'm going to deploy I have to do that first. Well, thanks to this deployment routine. By using Optimize CSS Assets Webpack Plugin and UglifyJS Webpack Plugin, css are extracted and included to the production or static files. Finally, after running the "npm run generate" and deploying it, css and fonts are included as static.

That's it for now. So many things to share but have a little time. 

Friday, July 13, 2018

Note : Using hidden for Laravel's model $append

Eloquent's mutator has been very helpful for making an additional attribute to a model. What is Eloquent mutator? According to Laravel's documentation, it says 

Accessors and mutators allow you to format Eloquent attribute values when you retrieve or set them on model instances.

Mutator is use along with an accessor, before accessor I usually use a method to return a custom field. For instance, I wanted my user model to return full name or lastname, firstname field. I would do the following


class User extends Model {
          public function fullname(){
                   return $this->firstname . " " . $this->lastname;
         }
}

My issue from above code is that I have to execute it each time I wanted to use it. Wouldn't it be nice if it's already attached along with your other attributes? How to do it?

Based on Laravel's documentation, accessor must be defined like a getter.

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{

    public function getFullNameAttribute()
    {
        return ucfirst($this->firstname) . " " . ucfirst($this->lastname);
    }

}
To attach it to the request just like the other attributes $appends property shall be added to the model.

The model will look something like this.
<?php 
namespace App; 
use Illuminate\Database\Eloquent\Model;
class User extends Model {
    protected $appends = array('fullname');
 
Since I'm using the append, mutators and accessors to a related table I noticed that related table will also be attached. Like in my post table, my post will have a user object attached into it. Check out the screenshot below. You will notice that user is attached to the post model. But I only wanted to append my custom field author.



Solutions:


  1. Add 'user' to the hidden property of the model and it will automatically hide the user object like this.
  2. Loop to the post collection and use the model method "makeHidden()". like this
           foreach($posts as $post){
                $post->makeHidden('user');
           }


And now the result will be something like this.

By using makeHidden, you can dynamically hide the mutator related table like user in my case. If it's in the hidden property of the model then it will not be in the attributes anymore. Unless the opposite  of makeHidden makeVisible method is use on the model.


Tuesday, July 10, 2018

Note: Fix on error BroadcastException in PusherBroadcaster.php line 106


While following a blog post on how to make a real-time Notification via Broadcasting using Pusher, it's expected to encounter some errors.

Basically I wanted to try how Laravel's Broadcasting works and use it in the future too. I didn't dwell on learning it before because some of the projects I worked with doesn't require a real-time updates. Though I've tested Firebase before but just testing if it connects to my Laravel App and nothing else. The fact that it was just a free trial account.

So today, I've finally tried a Pusher.com and Laravel's Broadcasting by following this blog. I though everything works but I noticed my Pusher's dashboard was not receiving any message at all.

The major error I've encountered is screenshot and copy-pasted below.

(1/1) BroadcastException in PusherBroadcaster.php line 106 at PusherBroadcaster->broadcast(array(object(PrivateChannel)), 'App\\Events\\MessageSent', array('user' => array('id' => 3, 'email' => 'meail@com.com', 'created_at' => '2018-06-23 08:50:41', 'updated_at' => '2018-06-23 08:50:41', 'firstname' => 'Ian', 'middlename' => null, 'lastname' => 'Villanueva', 'mobile_number' => null, 'status' => 0, 'birthdate' => null, 'address' => null, 'city_id' => null, 'country_id' => null, 'province_id' => null, 'profile_pic' => null, 'created_by' => null, 'updated_by' => null), 'message' => array('id' => 48, 'user_id' => 3, 'message' => 'coffee', 'created_at' => '2018-07-10 09:58:53', 'updated_at' => '2018-07-10 09:58:53'), 'socket' => null)) in BroadcastEvent.php line 49



As you can see above, there are no specific error to know how to fix it. Thanks to this Github discussion I was able to fixed it. And this for adding the ssl certificate to my localhost XAMMP.

Since, I got it working next up will be using it to ReactJS app and probably React Native later.


Monday, July 2, 2018

Putting validation rules at your models

Validation is one of the vital part of saving data coming from user. For instance you want to accept an email format but the user didn't supply the right data, that would be a disaster in a way, right?

Laravel's validation features has been there since the beginning but might as well use it. Basic usage of validation are as follows.

Include the Validator into your controller, in my case I like to use the following code snippet. 

$validator = Validator::make($request->all(),  [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]
);

          if ($validator->fails()) {
                    return response()->json([
                        'result' => $validator->messages(),
                        'message' => "Encountered validation error."
                    ], 400);

                  // redirect can also be put here.
            }

//code here if validation didn't fail


Code above starts by creating custom validation as stated from Laravel manual then checks if the validation failed. The creation of validation part can be repetitive in some cases and adding more conditions can be tricky since you have to look where controller did you use the rules.

I think it was from CakePHP that validation rules are put inside models so I applied similar thing.

In my models, I would put the following sample rules,

   protected static $rules = [
'title' => 'required|unique:posts|max:255',
'body' => 'required'
    ];

and a static function that basically returns the rules.

    public static function getRules() {
        return static::$rules;
    }

The in my controller's function, I would simply use

 $validator = Validator::make($input, Post::getRules());
Now, I can access or use my validation anywhere and update my rules in just one place which is the model.

In some cases, updating record is different from your create/new record rules so you can also put  the following function to your model

    public function getUpdateRules() {
        $updateRules = [];
        foreach(self::getRules() as $field => $rule) {
            $newRule = [];
            $ruleParts = explode('|',$rule);
            foreach($ruleParts as $part) {
                if(strpos($part,'unique:') === 0) {
                    if ( ! $this->isDirty($field)) {
                        $part = $part . ',' . $field . ',' . $this->getAttribute($field) . ',' . $field;
                    }
                }
                $newRule[] = $part;
            }
            $updateRules[$field] = join('|', $newRule);
        }
        return $updateRules;
    }

Credits: Found the code getUpdateRules function at StackOverflow.

That's it for now.



Saturday, October 14, 2017

Designing database for your Laravel Application

Laravel is one of the trending PHP frameworks for a couple years now. Most of its advantages and benefits are all said from the post I linked. From Laravel helpers, authentication tool, database migration and many more.

Of course, with the support of its community some developed a tool that to make the development even more faster.

Since most of the web / online systems development heavily involves database design, I would consider Laravel is second to none when it comes to its database tool. There's the migration and schema builder. It eases the database table creation and updates. If you are in a huge team, table design or updating are easily done by using migration tool.

On top of these tools, I personally recommend  Laravel Schema Designer website as part of database design. Laravel SD features helps its users to create, export and share your Laravel Schema. As a typical database design, you can design tables, add fields to it, add relationships to other tables. Since this is mainly for Laravel, the field type options such as nullable, fillable etc are all available. Here's a simple illustration I screenshot.


The best in all of this is the complete export which includes migration, controller, model with the relationships as designed like this.

namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
    protected $table = 'users';
    public $timestamps = true;
    public function role()
    {
        return $this->belongsToMany('Role');
    }
    public function attempts()
    {
        return $this->hasMany('Login_attempts');
    }
}
When all are set for your migrations, you can copy it to your laravel installation migration folder and execute the migration command to generate your schema. Some other files such as controllers are also available at php artisan commands so you might not need them anyway. In my case, I only use migration files.

That's what I can share for now.

I believe there are also other tools that is similar to the one I've posted. You can comment the tools you use in your Laravel development below.