teleren/devto huggingface dataset:
Breaking up the CircleCI yaml into multiple files
Tags: circleci, swissknife, buildpipelines, orbs
Published: 2020-04-13 15:55:10

As an org if you use CircleCI, over time you will notice that config file really increase in length. One of the repos I worked on hit ~3000 lines. It starts becoming unwieldy, reviewing changes is hard and making changes is harder still. Sadly CircleCI doesn't support reading from multiple files. But do not fret, this blog post will show you how you can do this.

Turns out Circle built most of what is required, into their CLI. Read about it here. Start out by breaking your config into multiple files as described in the circle article. You can see how I broke up my yml in [this repo](https://github.com/roopakv/circle-yml-split-example).

Through the rest of this post we refer to the smaller yml file as sub-ymls and the main config.yml as the config.

The `.circleci/src` directory contains the files that combine to to form `.circleci/config.yml`. We have a make command `make circle-config` which combines the sub-ymls to the main config

The interesting part which isn't covered by CircleCI is how you force a build to break if someone modifies one of the sub-ymls and forgets to compile the main config. Notice in the [lint and test file](https://github.com/roopakv/circle-yml-split-example/blob/master/.circleci/src/jobs/lint-and-test.yml#L6), we have a command that fails the build if CircleCI config was not generated.

```
- swissknife/build_and_check_circle_config:
    custom-error-message: Please run "make circle-config" and push up.
    fail-if-dirty: true
```

An example [pull request](https://github.com/roopakv/circle-yml-split-example/pull/1) shows how the build is failed if only the sub ymls and not the main config.yml is modified. This prevents divergence of code.

![Example Circle build showing fail if only sub yamls are modified](https://dev-to-uploads.s3.amazonaws.com/i/9bed09tlzuakhgvku7cl.png)

[Swissknife](https://circleci.com/orbs/registry/orb/roopakv/swissknife) is an orb, that has multiple useful commands and the `build_and_check_circle_config` commands fails the build if git is dirty after the circle config was generated.

In this example Swissknife checks if git is dirty after generating circle config. This means if anyone modified config directly or they modify the sub-ymls and not generate the config, the build will fail. The command can also be set up to push the difference in config to the origin.
Angular - How to pass arrays via Query Parameters
Tags: angular, angular11, queryparam, queryparameters
Published: 2020-04-13 15:36:52

---
title: Angular - How to pass arrays via Query Parameters
published: true
description: How to pass an array of values via query parameter in Angular.
tags: Angular, Angular11, QueryParam, QueryParameters
---

This is a quick guide on how to pass an array of values via query string in Angular. This is working in Angular 9+ as of 13/04/2020 but will most likely work just fine for any version from Angular 2+.

In the example below we will create an array of values in `ComponentA` and pass them to `ComponentB` via navigation. This method will work for a direct navigation to `ComponentB` via a link and also via programmatic navigation with the Angular router.

*The short version is: `JSON.stringify` your array and pass it as query param, thend `JSON.parse` it back into an array after navigation*

#### Component A - Passing the array
```javascript
export class ComponentA {
  
  // We need access to the Angular router object to navigate programatically
  constructor(private router: Router){}

  navigateWithArray(): void {
    // Create our query parameters object
    const queryParams: any = {};
    // Create our array of values we want to pass as a query parameter
    const arrayOfValues = ['a','b','c','d'];

    // Add the array of values to the query parameter as a JSON string
    queryParams.myArray = JSON.stringify(arrayOfVAlues);

    // Create our 'NaviationExtras' object which is expected by the Angular Router
    const navigationExtras: NavigationExtras = {
      queryParams
    };

    // Navigate to component B
    this.router.navigate(['/componentB'], navigationExtras);
  }

}
```

#### Component B - parsing the array
```javascript
export class ComponentB {
  // Where we will be storing the values we get from the query string
  arrayOfValues: Array<string>;

  // We need use the ActivatedRoute object to get access 
  // to information about the current route
  constructor(private activatedRoute: ActivatedRoute){
    
    // Get the query string value from our route
    const myArray = this.activatedRoute.snapshot.queryParamMap.get('myArray');

    // If the value is null, create a new array and store it
    // Else parse the JSON string we sent into an array
    if (myArray === null) {
      this.arrayOfValues = new Array<string>();
    } else {
      this.arrayOfValues = JSON.parse(myArray));
    }
  }

}
```

#### Enjoy
DevOps & Chill n.3: Creating a LEMP Playbook with Ansible
Tags: devops, beginners, videos, ansible
Published: 2020-04-13 15:29:12

---
title: DevOps & Chill n.3: Creating a LEMP Playbook with Ansible
published: true
description: In the third episode of DevOps&Chill, we'll create an Ansible playbook to automate setting up a LEMP server.
tags: devops, beginners, videos, ansible
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/01kouf8jrphzq9pqw4yz.png
series: DevOps & Chill
---

In the third episode of DevOps&Chill, we create an [Ansible](https://ansible.com) playbook to automate the steps necessary to install and set up a LEMP server on Ubunbtu 18.04, using a couple DigitalOcean droplets as nodes.

This video was edited from the original stream in order to be more succinct and in a faster pace. 

{% youtube VhJr-2Oxy-4 %}

## The Playbook

The final playbook we created in this video is included below for easier access:

```yaml
---
- hosts: all
  become: yes
  vars:
    - install_packages: [ "nginx", "php-fpm", "mysql-server", "python3-pymysql" ]
    - http_port: 80
    - http_host: "{{ ansible_facts.eth0.ipv4.address }}"
  tasks:
    - name: Update cache and Install Required Packages
      apt:
        name: "{{ install_packages }}"
        state: latest
        update_cache: yes

    - name: Removes anonymous MySQL accounts
      mysql_user:
        name: ''
        host_all: yes
        state: absent
        login_unix_socket: /var/run/mysqld/mysqld.sock
      no_log: true

    - name: Allow access on port 80
      ufw:
        rule: allow
        port: '80'
        proto: tcp

    - name: Set Up Nginx default site
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/sites-available/default
      notify: restart nginx

    - name: Set Up php test page
      template:
        src: phpinfo.php.j2
        dest: /var/www/html/info.php
    
  handlers:
    - name: restart nginx 
      service:
        name: nginx
        state: restarted

```

To run this playbook, you'll need an [Ansible Control Node](https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-ansible-on-ubuntu-18-04) set up with at least one managed node in your inventory file. Then, you can execute this with the following command:

```bash
ansible-playbook -i hosts lemp-playbook.yml -u USER
```

Where `hosts` is your inventory file name, and `USER` is the remote user you're using to connect via SSH on the remote server and run the Ansible commands. This should be either a `sudo` user or `root`.

Feel free to use the comments section to ask question and to suggest new topics for [DevOps&Chill](https://twitch.tv/erikaheidi). Cheers!
Tutorial: Web Scraping with Python on the Cloud
Tags: python, webdev, beginners
Published: 2020-04-13 15:26:16

##Introduction
Web scraping on the cloud has never been easier. Setting up an automated web scraping script on WayScript only takes a few minutes to do.

##Prerequisites
No prerequisites but some content you might find helpful:
[Working with Python](https://docs.wayscript.com/library/modules/python?src=DEV)

##Automating a Script to Run Daily
Most things you create on WayScript can be activated daily by using a time trigger. When setting up the time trigger, we select our time that we want the script to run, and build the script below that tree in the workflow.

![Trigger](https://cdn.wayscript.com/blog_img/70/1.png)

##Scraping our content
We'll scrape our content in this example by using the python module. We'll drag this into our workflow and write some code that looks like this:

<pre>
import requests
from bs4 import BeautifulSoup

ticker = 'AAPL'
url = 'https://finance.yahoo.com/quote/' + ticker

res = requests.get( url )
html = res.text

soup = BeautifulSoup( html, 'html.parser' )
market_cap_elem = soup.find( 'td', { 'data-test' : 'MARKET_CAP-value' } )
market_cap = market_cap_elem.text

print( ticker, 'Market Cap', market_cap )

variables[ 'MarketCap' ] = market_cap</pre>

With that code, we'll go and scrape information off another webste, and return it to our script as a variable using the variables dictionary. We'll use it to send ourselves a text message.

![Variables](https://cdn.wayscript.com/blog_img/70/2.png?src=DEV)

##Questions, Concerns?

If there's any questions feel free to message us on discord. We're happy to help! If you want to see this full script template, you can find it [here](https://wayscript.com/user/derrick/sRN003of?src=DEV).
Conditional rendering in React - the "if/ else" method
Tags: react, components, beginners, tutorial
Published: 2020-04-13 15:17:49

When developing in React, there's often the case that we want to hide or show certain parts of the application, depending on some conditions. Let's say we want to hide a dialog box when the user clicks the `"x"` icon. Or we want to display a different color scheme (dark or light) based on what the user selects. Rendering UI elements depending on certain conditions has a name and that is `conditional rendering`.

There are multiple ways to achieve this and because this is a complex topic, I will break it down in smaller pieces so I can explain each of them as best as I can. Today I'm going to talk about the `if/else` method and I'm going to provide code snippets to better illustrate what I mean.

We can use if/else the same way we would use it in Javascript. If a condition is true, we render something, if not, we render something else. Pretty easy, no? Now let's see it in action:

**Condition1 component**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/1zbkh79t09gtgc1mez09.PNG)

**Condition2 component**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0lfh1zsxmg9zsmvgh32w.PNG)

We have three functional React components called `Condition1`, `Condition2` and `App`. In our example, the "App" component will render "Component1" or "Component2" conditionally, depending on the button clicks. We use one of the React hooks, `useState`, to manipulate the state of the button. We start with the condition being "false" and every time the button is clicked, the state gets set to the opposite of the current value(that's why we use "!condition").

**App component**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/69iehmgtigizpyev3j6d.PNG)

This is a simple idea but with some twitching we could use this code to implement a color scheme, for example (every time the user click's the button, a different CSS style is applied to the page). Bellow I added the whole code again, in case you would like to copy/ paste it in your work space. Next time I'll write about achieving conditional rendering using the `ternary operator`.

```react
import React, { useState } from "react";

const App = () => {
  let codeToDisplay = null;
  const [condition, setCondition] = useState(false);

  const handleConditionChange = () => {
    setCondition(!condition);
  };

  if (condition) {
    codeToDisplay = <Condition1 />;
  } else {
    codeToDisplay = <Condition2 />;
  }

  return (
    <div>
      <button type="button" onClick={handleConditionChange}>
        Click
      </button>
      {codeToDisplay}
    </div>
  );
};

const Condition1 = () => {
  return (
    <div>
      <p>If true, display this!</p>
    </div>
  );
};

const Condition2 = () => {
  return (
    <div>
      <p>If false, display this!</p>
    </div>
  );
};
```
Project Euler: Problem 6 Overview
Tags: projecteuler, algorithms
Published: 2020-04-13 21:19:51

---
title: Project Euler: Problem 6 Overview
published: true
date: 2020-04-13 15:00:00 UTC
tags: Project Euler,algorithms,project euler
canonical_url: 
---

In this article, we’ll be exploring Project Euler problem 6. I’ll provide some ideas and hints, but it’ll be up to you to create a...

The post [Project Euler: Problem 6 Overview](https://jaeheonshim.com/project-euler-problem-6-overview/) appeared first on [Coding with Jaeheon Shim](https://jaeheonshim.com).
Faster searches with Firefox
Tags: productivity, firefox
Published: 2020-04-13 14:36:27


This post is about 2 things: Improve time spent on searches, and improve time to reach your bookmarks.

## Faster searches

For work purposes, I need to use the Google search engine as it is very performant for tech searches (sorry [duck.com](https://duck.com)). But something I missed from duckduckgo was the [bang option](https://duckduckgo.com/bang). 

With the duck search engine, if you want to search something specific on **google maps**, just start your search with `!gm Hamburg` and it redirects you on google maps with the search ready.


I discovered you can add the same with firefox (❤️)! 

Just right click on any search bar and choose the option `Add a Keyword for this Search...`. Then choose the keyword you are comfortable with. 

Mine are:

```sh
gi => google images
gm => google maps
yt => youtube

amz => amazon.com
amzde => amazon.de
amzfr => amazon.fr

rotten => rottentomatoes.com
wiki => wikipedia.org
wikifr => wikipedia.fr

trad => WordReference.com
```

Combined with the tab opener shortcut, it is just blazing fast: 

* `CMD + T`
* `yt eiro nareth`

Instead of doing something like: 

* `Open new tab`
* `Search Youtube`
* `Click on the search bar and write your search`

Documentation here: https://support.mozilla.org/en-US/kb/how-search-from-address-bar

## Faster navigation

In the same way as above, it is possible to use a keyword to reach a bookmark.

Let's say I often go to the bitbucket repositories page, and therefore it is in my bookmarks folder. But I decided to hide the bookmarks toolbar because it takes space on the screen. 

For example, to access my bitbucket bookmark, it is still possible with just searching `repos`. Here is how to do it:

* Open your bookmarks (With `CMD + B`)
* Right click on one of them
* Choose properties option 
* Add a keyword

From now on, everytime you search this keyword in the search bar it will directly redirect you to your bookmark.

Some of mine:

```sh
mailpro => My email address
mail => My normal email

repos => bitbucket repositories
sprint => Sprint dashboard

lastyt => youtube.com/feed/subscriptions
```

Originally published [here](https://blog.lepape.me/faster-searches-with-firefox).
SPA fallback for Static Sites
Tags: nuxt, vue, jamstack, static
Published: 2020-04-13 14:43:07

As you know in Nuxt.js you can work with static sites with very little configuration. If you already have a Single Page application and you want to convert it to a static site all you have to do is change the mode from 'spa' to 'universal' in your nuxt.config.js file. If you are already running a universal app then you won't need to modify this. 

```javascript
mode: 'universal'
``` 
Then all you have to do is change your build command in Netlify or Azure or wherever your site is being hosted. Instead of using the 'build' command you use the 'generate' command. And that's it. Now your site is a static site. 

```bash
yarn generate
```

Everything will be rendered during the build phase which means no need for a server so you can deploy your site for free to Netlify or other static hosting services. And you will have great SEO as everything has already been generated as opposed to a SPA which is generated on client side when the app is launched. 

There are also many other benefits of creating static sites such as performance and security.

But what happens when you want to add things to your static site such as a login area or a booking engine. How do we deal with these scenarios? This is where SPA fallback comes into use with the exclude option. Exclude accepts an array of regular expressions and will prevent the generation of these routes however thanks to SPA fallback when set to 'true' they will still be accessible. 

Exclude all routes with the word booking:
```javascript
export default {
  generate: {
    fallback: true,
    exclude: [/^(?=.*\booking\b).*$/]
  }
}
``` 
Exclude all routes starting with the word admin:
```javascript
export default {
  generate: {
    fallback: true,
    exclude: [/^\/admin/]
  }
}
``` 
We can also just exclude a complete folder:
```javascript
export default {
  generate: {
    fallback: true
    exclude: [/booking/, /admin/]
  }
}
``` 

We can now basically have a single page application inside our static site. Very cool indeed.
Depois do Café - Episodio 7 - Corona Edition: Trabalhando em Ambientes Internacionais
Tags: podcast, corona, ambientesinternacionais, portugues
Published: 2020-04-13 14:35:55

---
title: Depois do Café - Episodio 7 - Corona Edition: Trabalhando em Ambientes Internacionais
published: true
description: Nesse episódio corona edition a gente fala sobre a nossa experiência de trabalhar em um ambientes internacionais, nós comentamos como foi começar a trabalhar em Inglês e com pessoas de outras nacionalidades, além de brasileiros. 
tags: podcast, corona, ambientes-internacionais, portugues
canonical_url: https://anchor.fm/depoisdocafe/episodes/Episodio-7---Corona-Edition-Trabalhando-em-Ambientes-Internacionais-ecnr1k
---

{% spotify spotify:episode:1Loh4oPJdB0WjWiV1732qf %}

Você também pode ouvir no seu aplicativo preferido: [iTunes](https://podcasts.apple.com/br/podcast/depois-do-caf%C3%A9-com-airton-zanon/id1480842641), [Breaker](https://www.breaker.audio/depois-do-cafe-com-airton-zanon), [Google Podcasts](https://www.google.com/podcasts?feed=aHR0cHM6Ly9hbmNob3IuZm0vcy9lMGU0MDU4L3BvZGNhc3QvcnNz), [Overcast](https://overcast.fm/itunes1480842641/depois-do-caf-com-airton-zanon), [Pocket Casts](https://pca.st/bpyo3i4y), [Radio Public](https://radiopublic.com/depois-do-caf-com-airton-zanon-6r2oLq), [Spotify](https://open.spotify.com/show/4cqX5o40bClwqtYHv9X7Lp)

Nesse episódio a gente fala sobre a nossa experiência de trabalhar em um ambiente internacional aqui na Holanda, nós comentamos como foi começar a trabalhar em Inglês e com pessoas de outras nacionalidades, além de brasileiros.

Este foi um episódio da Série Corona Edition, na qual vamos lançar um episódio menor que o normal toda semana, durante este lockdown, para comentar o que estamos fazendo depois do café.

----------------------

Participantes:

Airton Zanon - [@airtonzanon](https://twitter.com/airtonzanon) (twitter)
Elisa Pedrosa Reis - [@liisapedrosa](https://twitter.com/liisapedrosa) (twitter)

----------------

Links comentados:

Canal do youtube do Gavin: https://www.youtube.com/channel/UCskEPRzGlsYHs_a5SJyCXag
Canal Slack de Brasileiros Expatriados: https://join.slack.com/t/brazil-tech-expats/shared_invite/zt-975uiifq-CxUOV4cdyMgG9~bF5mCvHg

----------------

 Para mais episodios e saber mais sobre o podcast acesse https://anchor.fm/depoisdocafe.

Siga-nos no twitter [@dpsdocafe](https://twitter.com/dpsdocafe)
Git alias to delete merged branches
Tags: git, bash
Published: 2020-04-13 14:21:05

When you develop a project using multiple branches you may end up with a situation where you have branches which have already been merged into another branch and now serve no purpose.

I've created a git alias that deletes every branch that is already merged into `master` or another branch provided as an argument. To use it you need to modify `.gitconfig` and add following lines into it
```.gitconfig
[alias]
  cleanup = "!f() { git branch --merged ${1:-master} | egrep -v \"(^\\*|${1:-master})\" | xargs --no-run-if-empty git branch -d; };f"
```
You can execute given command inside your terminal to achieve the same effect
```
git config --global alias.cleanup '!f() { git branch --merged ${1:-master} | egrep -v "(^\*|${1:-master})" | xargs --no-run-if-empty git branch -d; };f'
```

Then you can remove branches merged into `master` by invoking `git cleanup`. You can also provide a branch as an argument if your want to clean up a different branch eg. `git cleanup development`
Patrones de diseño en #javascript - Factory
Tags: javascript, design, designpatterns, codenewbie
Published: 2020-04-13 14:20:36

Este patrón de diseño te va a ayudar a crear objetos o clases de tipo similar, cuando no sabes exactamente de qué tipo serán finalmente o cuales vas a utilizar.

Según vayas creando tu proyecto vas a decidir cuales vas a instanciar.

Clases u objetos **Similares**, te voy a dar un ejemplo:

```javascript
// Imaginemos que tenemos una pequeña app que crea Webs

function constructorSitios() {
     // creamos el método
     this.crearElemento = (texto, tipo) => {
          let html;
          
          if (tipo === 'input'){
               html = new InputHTML(texto)
          } else if (tipo === 'img'){
               html = new ImangenHTML(texto)
          } else if (tipo === 'h1'){
               html = new HeadingHTML(texto)
          } else if (tipo === 'p'){
               html = new ParrafoHTML(texto)
          }
          html.tipo = tipo;
          return html;
     }
}

```
Como vemos, los objetos declarados son objetos similares, son relacionados y comparten mismas propiedades, en este caso la variable texto.

```javascript
// Ahora imaginemos que necesitamos crear un H1
// Creamos el constructor HeadingHTML
const HeadingHTML = function(texto){
     this.texto = texto;
};
const sitioWeb = new constructorSitios();
sitioWeb.crearElemento('Bienvenidos', 'h1') );
```
Esto llamará al método que declaremos en nuestra función y una vez pasada la condición if, creará una nueva instancia de *HeadingHTML*, a su vez le pasamos el texto (Bienvenidos), obteniendo como resultado un objeto que contiene un H1.

`HeadingHTML {texto: "Bienvenidos", tipo: "h1"}`

### En resumen
El factory abre un abanico de posibilidades al trabajar con objetos similares sin tener que duplicar código, solo deberás instanciarlo!.