Naguel

I'm Nahuel, and these are my work experiences, ideas and thoughts as a web developer working on the eCommerce industry.

A few soft skills interview questions to get to know the candidate

A few soft skills interview questions to get to know the candidate

For job interviews to fill a technical role it's obvious that the questions needs to be, well, technicals, with focus on the hard skills questions aiming to know the candidate's knowledge in a specific framework, code language, software, etcetera.

But the attitude is very very very... very much... important. I said it before:

Everybody has access to the same documentation, to the same in-house training programs, to the same software, to everybody's code, to basically the same people to ask questions and to learn from... and what's set the difference between someone progressing in his or her line of work and someone stuck is the personality each developer has.

Soft skills related questions allow you to get to know the human you are interviewing, having in mind that you'll share with that person more than some lines of code if you ended up offering the job.

It also humanise the interview. If you pay attention people are usually tense answering the technical questions but when you throw in a soft skills one candidates relax and enjoy the conversation created around that question.

Developer’s work success being too much about personality rather than hard skills
Everybody has access to the same documentation, the same in-house training programs, to everybody’s code, to the same people to ask questions and to learn from... and what’s set the difference between someone progressing in his line of work and someone stuck is the personality each developer has.

At my current job we have a few very good soft skills questions I would like to share now in case you find them useful (our interviews are for web developers so the questions, while soft skills related questions, orbit around that role).

What do you think makes a good developer?

I personally expect whatever answer that's not about code, software, or any other hard skill stuff.

People usually talks about the ability of being flexible, passionate about it, the importance on working as part of a team, etcetera. Still some candidates mention hard skill stuff not covered before in the interview such as testing, and that's fine.

What do you think makes a good manager?

I like this one because it's a chance for the candidate to talk about others, and it's expected that they think of their current boss (obviously).

The answer will give you an idea of how the candidate works on a team structure where somebody is on a position above them. And at the same time it will hint you if the candidate will do well with the current managers at your company.

I like the answers about leadership and motivation.

What do you think you would add to the team if you were to get the job?

This is the polite version of "Why do you want this job besides money?".

I like this one because it forces the candidate to summarise what's their contribution to the team. And it's important to emphasise the team in the question, like you are not just adding something to the company but adding something to a team made of real humans.

What would you expect from the team if you were to get the job?

In opposition to the previous one, this is the time for the candidate to tell us how they see themselves after any period of time as part of a new team.

Again, we are asking about the team, not the company, so we try to keep it human while guiding the candidate into giving us something not technical.

If you were to organise a work social night out, what would you plan?

This always takes the candidates by surprise. They are thinking about PHP, VueJS, code reviews, pull requests and out the sudden they need to think about beers (because beers is the right answer to a social night out plan).

What do you like to do when you aren't coding?

There's no better question than this one to force the candidate to stop talking about hard skills and say something about their personal life (as much as they want, don't force people into talking about their personal life on a job interview).

It is also fun to learn about others people hobbies.

Proper way to configure asynchronous email sending in Magento

Proper way to configure asynchronous email sending in Magento

There are two ways to configure how Magento send order related emails (order confirmation, invoice, shipment and credit memo emails):

  • Either immediately when an action is performed (for example, right after you place an order).
  • Or cron-based (asynchronous).

Magento itself recommends to configure this to be asynchronous for performance reasons, so the email dispatch process doesn't block nor delay what the customer is doing (for example, less time consumption when the customer is placing an order), or to avoid long cron runs (or total crons block) when an ERP is updating orders status in bulk.

Enabling the “Asynchronous email notifications” setting moves processes that handle checkout and order processing email notifications to the background.

Configuration best practices by Magento

For my personal experience, it is also recommended to configure emails sending to be asynchronous to avoid having unsent emails.

When this is configured as immediately (not async), if an email fails to be dispatched because of any reason (like a server timeout) then Magento won’t try to send that email again in the future and the customer won’t be ever notified of his/her action.

Basically, there are a lot of good reasons to have this to be async.

Before setting this up

If you are going live for the first time on a new site there's not much to worry about, but if you are changing this setting from not-async to cron-based on an already live site then there's something to consider first.

The way this works when it's configured to be async is that Magento will rely on a cron to pick up from the database (from those tables related to Orders, Invoices, Shipments and Credit Memos) all those entities where the email was not dispatched, and it will send it.

Problem is that Magento doesn't care much about the date of those entities.

For example, if there’s an Order from 2019 whose order confirmation email was not sent because of any reason (for example, because there was a PHP error that stopped the execution), the cron will now pick this Order up and Magento will send the email related to that order.

To avoid this behaviour we should mark all pending emails from Orders, Invoices, Shipments, and Credit Memos as if they doesn't need to be dispatched, which can be done by executing the following SQL statements before enabling the asynchronous sending.

UPDATE sales_order SET send_email = 0;
UPDATE sales_invoice SET send_email = 0;
UPDATE sales_shipment SET send_email = 0;
UPDATE sales_creditmemo	 SET send_email = 0;

What we are doing here is ignoring the sending of emails for old Orders (and Invoices, Shipments and Credit Memos) so when we change this to be async the cron will only cares for future stuff.

Changing the configuration

Enable the “Asynchronous sending” option under “Stores → Settings → All Stores → Sales → Sales Email → General Settings”.

Unable to load dynamic library 'pgsql.so'

Unable to load dynamic library 'pgsql.so'

I had this weird issue that seems to be related to macOS Big Sur and MAMP, allegedly, either both combined or when upgrading any of those two (or both?).

I don't know exactly why this happened to me out of the sudden (I blame MAMP as it was the last thing that I updated) but I managed to fix it anyway.

PHP Warning:  PHP Startup: Unable to load dynamic library 'pgsql.so' (tried: /Applications/MAMP/bin/php/php7.3.21/lib/php/extensions/no-debug-non-zts-20180731/pgsql.so (dlopen(/Applications/MAMP/bin/php/php7.3.21/lib/php/extensions/no-debug-non-zts-20180731/pgsql.so, 9): Library not loaded: /Applications/MAMP/Library/pg/lib/libpq.5.dylib
  Referenced from: /Applications/MAMP/bin/php/php7.3.21/lib/php/extensions/no-debug-non-zts-20180731/pgsql.so
  Reason: image not found), /Applications/MAMP/bin/php/php7.3.21/lib/php/extensions/no-debug-non-zts-20180731/pgsql.so.so (dlopen(/Applications/MAMP/bin/php/php7.3.21/lib/php/extensions/no-debug-non-zts-20180731/pgsql.so.so, 9): image not found)) in Unknown on line 0

To get around this situation, many suggest to update Brew with brew update. That didn't work for me (and to be honest I can't see what's the relationship with Brew and MAMP) but you can give it a try anyway since it's easy to do.

What's interesting about the error above is that it mentions pgsql.so.so which is clearly wrong because of the double .so extension.

So how do I actually fix this issue?

Go to that extensions subfolder mentioned in the error (for example, mine is /Applications/MAMP/bin/php/php7.3.21/lib/php/extensions/no-debug-non-zts-20180731/) and create a symlink for pdo_pgsql.so called pdo_pgsql.so.so by doing:

ln -s pdo_pgsql.so pdo_pgsql.so.so

Now it doesn't matter what MAMP is looking for as it will find it either way.

That's not all. Go to /Applications/MAMP/Library/pg/lib and you'll notice something really weird which are broken paths for the symlinks libpq.5.dylib and libpq.dylib as seen below.

Again, how that happened is another mystery. But it doesn't matter, let's just fix those symlinks by deleting them and creating them again.

ln -s libpq.5.7.dylib libpq.5.dylib;
ln -s libpq.5.7.dylib libpq.dylib;

As you can see on the previous screenshot, the symlink libpq.5.dylib points to a broken path for libpq.5.7.dylib which is basically right there on the same folder. The same goes for libpq.dylib.

At the end everything should look like the following:

Magento and a deadlock found when trying to get lock

Magento and a deadlock found when trying to get lock

"What now?" issues every now and then with Magento are the norm, and I got this one a few days ago:

SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction, query was: INSERT INTO `catalog_product_index_eav_temp` SELECT DISTINCT [...]

Apparently the server went down for a second, or MySQL went down... or something happened and a reindex process was interrupted (in my case the one for the "Product EAV" index), and there was no way to make it work again.

Even the usual bin/magento indexer:reset and then a manual reindex with bin/magento indexer:reindex didn't do the trick and the only difference was that instead of the previous error I was getting the classic one.

Product EAV index is locked by another reindex process. Skipping.

Lucky me, I find the following on Twitter.

Basically, when you have no way to "unlock" an index, and after you already tried the reset and manual reindex, just change that prefix in your app/etc/env.php file to something new, then reset and finally try to reindex again.

That alone should do the trick.

Add related posts to Ghost blog

Add related posts to Ghost blog

The related posts are quite easy to add to Ghost if you have some basic knowledge on how to edit your current theme (there's no option to turning this ON and OFF on the Admin, unfortunately, so you must do it on the theme itself).

If you open your theme's files you would see a post.hbs template which is the one for the articles (for "this page you are seeing right now", basically), and the block expression {{#post}}...{{/post}} would be the one containing everything related to the post itself.

Outside that expression, after it, we want to add the related posts taking advantage of the {{#get}} helper.

{{#get}} is a special block helper that makes a custom query to the Ghost API to fetch publicly available data.

get documentation for Functional Helpers by Ghost

Clearly, you can use this helper to get the related posts anywhere you want, like on the sidebar of the blog if yours have one, or in a page instead of a post (but I personally like them at the end of an article).

Let's say you would like to get a list of related posts based on the tags of the current one, which can be done by filtering the data on the filter attribute.

{{#get "posts" filter="tags:[{{post.tags}}]+id:-{{post.id}}" as |related|}}
	[...]
{{/get}}

In this case the filter attribute also contains id:-{{post.id}} to ignore, from the list of posts we are getting, the current article (we wouldn't want to suggest as related post the same post the user just read).

You can add as many filters as you want using the + sign as separator.

Inside this helper, the related "object" will be the one containing all the related post, so you just need to "loop it".

{{#get "posts" filter="tags:[{{post.tags}}]+id:-{{post.id}}" as |related|}}
    <div class="related-posts-wrapper">
        {{#foreach related}}
            <article class="{{post_class}}">
                <a href="{{url}}">{{title}}</a>
            </article>
        {{/foreach}}
    </div>
{{/get}}

Once inside the foreach you are in the context of the post, and then you can just get whatever you want from that post such as the {{url}}, {{title}, etcetera.

You can limit how many post to show by using the limit attribute on the {{#get}} helper (15 by default, which seems like too much)

{{#get "posts" limit="2" filter="tags:[{{post.tags}}]+id:-{{post.id}}" as |related|}}
    ...
{{/get}}

The related posts can be anything you like and you would like to consider as related posts, as you are not limited to that filter for the tags I used as an example.

I'm currently using tags:[{{post.primary_tag.slug}}] within the filters to only consider those posts that have the primary tag of the current post as a tag in any position, as I think those posts would be more relevant to the current one.

{{#get "posts" filter="tags:[{{post.primary_tag.slug}}]+id:-{{post.id}}" as |related|}}
    ...
{{/get}}

This is not the same as using primary_tag:{{post.primary_tag.slug}} which is another filter option, in this case to get only those posts that their primary tag is the same as the current post (there's a slightly difference).

Optionally, you can use the featured:true filter option to get those posts that are checked as featured within the Admin.

{{#get "posts" filter="tags:[{{post.tags}}]+featured:true+id:-{{post.id}}" as |related|}}
    ...
{{/get}}

If you have multiple writers in your blog and you want to show related posts where the current author also participates you can use the authors:{{post.primary_author.slug}} option within the filters.

{{#get "posts" filter="authors:{{post.primary_author.slug}}+id:-{{post.id}}" as |related|}}
    ...
{{/get}}

This is different than using primary_author:{{post.primary_author.slug}} where we are filtering by those posts where the primary author is the same.

Refer to the get documentation on Ghost for more ideas on how to filter.