dev.to – p.53.441

 

Help

DEV Community

The most recent home feed on DEV Community.

Do you need GraphQL with Django?

26 Nov 2019, 5:00 pm

Written by Tigran Bayburtsyan✏️

For the past 5 years, Django has been the most effective framework for making quick web applications, API Endpoints, or Admin panels for other applications.

One of the biggest advantages of Django is its ability to enable users to write less code and get started quicker, especially if you’re including an admin panel and a fully-manageable database migration process as base functionality.

Django Rest Framework—an external toolkit—makes it easy to build API endpoints. It basically wraps full CRUD API around the Django Model with just a few lines of code.

This means that building any basic CRUD API with Django helps to keep more of a development focus on UI parts, which are key elements of all software products.

Similarly, GraphQL aims to automate backend APIs by providing type strict query language and a single API Endpoint where you can query all information that you need from UI and trigger actions (mutations) to send data to the backend.

My journey with GraphQL started with Facebook’s API, where GraphQL comes from.

Naturally, GraphQL is considered to be very close to the JavaScript world, mostly because browser-based apps are the first adopters of that technology.

That’s why my first GraphQL server+client was done in Node.js and React.js. After having the first app built on top of GraphQL API, I started to use it exclusively for my Web-based projects.

LogRocket Free Trial Banner

Advantages of GraphQL

As you may have guessed, there is a library for Django to support GraphQL called Graphene Django, which is very similar to the Django Rest Framework.

However, there are significant differences between Django Rest and Django with GraphQL.

The key difference lies in UI usability: with Rest API, you’re getting endless URLs with specific parameter names where you have to check types and specific values.

Meanwhile, with GraphQL you’re defining mutation similar to the code below and getting strictly defined variable names and types, which become part of an automatic GraphQL type validation.

type Mutation {
  userLogin(email: String!, password: String!): UserLoginResponse
}

type UserLoginResponse {
  token: String
  error: Boolean
  message: String
}

GraphQL also comes with another bonus packaged inside its type system. It automatically generates documentation where you can get available queries and mutations with their parameters/return types.

Django Rest also generates some form of documentation, but it is not as usable as the GraphQL Playground displayed below.

prettify-nocdn.png

If you think this type of interface is available for all kinds of GraphQL endpoints, you’re wrong — this is only available in development mode servers.

In terms of security, having one API Endpoint is naturally more manageable than having hundreds of them—especially when you consider the fact that GraphQL automatically keeps specific type rules and won’t allow requests with incorrect parameter names or values.

Django GraphQL

Let’s make a basic setup with Django and GraphQL just to demonstrate how powerful this setup can be. On one hand, you’re getting easy CRUD management with database. On the other hand, you’re getting a very powerful API query language with a single endpoint.

Installation should be very easy. Just follow the steps defined here: https://github.com/graphql-python/graphene-django

The interesting parts are defining GraphQL types and queries in Python. It’s actually based on your database models, but you can also define custom queries without using Django Models.

# schema.py
from graphene_django import DjangoObjectType
import graphene
from .models import Post as PostModel
from .models import User as UserModel

class Post(DjangoObjectType):
    class Meta:
        model = PostModel
        interfaces = (relay.Node,)

    @classmethod
    def get_node(cls, info, id):
        return Post.objects.get(id=id)

class User(DjangoObjectType):
    class Meta:
        model = UserModel
        interfaces = (relay.Node,)

        posts = graphene.List(Post)

    def resolve_users(self, info):
                return Post.objects.filter(user=self)

    @classmethod
    def get_node(cls, info, id):
        return User.objects.get(id=id)

class Query(graphene.ObjectType):
    users = graphene.List(User)

    def resolve_users(self, info):
        return UserModel.objects.all()

schema = graphene.Schema(query=Query)

Now you can very easily query all users with their posts.

The most important thing to remember is that you can query fields you want, which will affect the overall load time and traffic usage on the UI side.

For larger user bases, it’s important to keep traffic low and only query the fields you need. In the case of Rest API, you will get all fields anyway.

query {
  users {
    name
    posts {
      id
    title
    content
    }
  }
}

This is the basic query outcome from the Python definition, which is pretty simple and — compared to Rest API — more expressive than you may think.

What about GraphQL Subscriptions?

GraphQL Subscriptions function as a way to tell the server to retrieve data based on a specific query whenever the data is available.

It all works with WebSockets in near-real time, which means we have to somehow include Django Websockets and configure our backend server for accepting WebSockets.

Basically, GraphQL is just an API query language interpretation that works with any kind of network transportation when handling client and server-side GraphQL language interpretation.

It may seem difficult at first, but there’s an open-source library and Django GraphQL Subscriptions over at the Django Websockets module.

# settings.py

GRAPHENE = {
    'SCHEMA_INDENT': 4,
    'MIDDLEWARE': [
        # Others middlewares
        'graphene_django_subscriptions.depromise_subscription',
    ]
}

This will be enough to handle the subscription schema later on as a Subscription query.

A quick aside: Pinterist actually works entirely on GraphQL Subscriptions, which is all built on top of Django Backend (but probably modified a lot.)

Conclusion

In my opinion, Django with GraphQL is more powerful and extensible than Django with Rest API.

However, it isn’t battle-tested and large companies are still in the process of adopting this kind of combination, but based on what you can get out of this simple configuration, imagine how much more comfortable web development will be when you use Django with GraphQL with modern technologies.

Editor's note: Seeing something wrong with this post? You can find the correct version here.

Plug: LogRocket, a DVR for web apps

 
LogRocket Dashboard Free Trial Banner
 
LogRocket is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
 
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
 
Try it for free.

The post Do you need GraphQL with Django? appeared first on LogRocket Blog.

★ freek.dev turns five!

26 Nov 2019, 4:04 pm

How time flies. My blog is again one year older. I've been running it now for five years. Like all the previous years, I'd like to give an overview of everything that's happened on this blog in the past year.

A lot of things have changed

This year a couple of significant changes happened. I've changed the domain of the blog from murze.be to freek.dev. I think for most people it easier to remember that URL, since it's my first bit. A cool bit of trivia: murze is the short version of my third name, which is Murzuplus. Yeah, my parents named by after a Byzantian emperor. Lucky, they chose it as my third name and not the first.

The second big change that happened in 2018 is the refreshed look. I'm very grateful for the work my colleague Sebastian put into this. He also refreshed the look of my newsletter template.

A smaller change that happened a couple of months ago is the removal of Disqus powered comments. Even though functionally Disqus does the job, I felt that, because comments couldn't be styled, the comments felt out of place. They have been replaced by webmentions. Here's how you can add them to your Laravel powered blog.

Around August, I played a bit with LiveWire by Caleb Porzio, a cool way of adding dynamic content without the need of having to write JavaScript yourself. Here's the commit that replaces the previous JS powered search with a Livewire component.

freek.dev by the numbers

The past 365 days, the blog served about 903 064, which is a nice 20% increase compared to last year. In the past 12 months, I published 292 posts of which I've written 45 myself. In total, there are now 1509 posts, and of 240 of those, I'm the author.

Here's the top 10 most visited posts:

  1. Introducing laravel-websockets, an easy to use WebSocket server implemented in PHP
  2. Searching models using a where like query in Laravel
  3. My current setup (2019 edition)
  4. Refactoring to actions
  5. The value of the void typehint in PHP
  6. Simplifying controllers
  7. Ignition: a new error page for Laravel
  8. Getting started with Domain Oriented Laravel
  9. Tools to automatically format PHP, JavaScript and CSS files
  10. Configuring PhpStorms code generation

Original content

Here are links to 45 posts I wrote in the past year.

In closing

I hope you've enjoyed freek.dev and that you'll continue reading it in the next 12 months.

Collection of Linux Resources

26 Nov 2019, 4:00 pm

Below, you'll find a collection of Linux resources categorized into resource types - videos, books, sites, etc. I hope it will serve you well in your journey of becoming a Linux Master 😉

For the most updated version of this page, please visit here

Learn Linux Sites for Beginners

Name Description
Linux Journey Guides ordered by topic with exercises
Techmint Linux written articles/lessons
Linux Survival Interactive guide
Linuxcommand Learn the ways of the command line
Ryanstutorials written guides for beginners
Vim Adventures Learn how to use Vim by playing a game
LYM Focuses on the command line. While it's great, I wouldn't start from it

Linux Videos

Blogs & News sites

Name Comments
Phoronix News
nixCraft Blog, Linux Tips, Hacks, Tutorials
thegeekstuff Blog on Linux, Open Source and other topics
Brendangregg Blog which focuses on Linux Performances
Enable Sysadmin Red Hat blog which focuses on Linux System Administration

Linux Books

Title Comments
The Linux Command Line Free. Great for learning the command line
Linux Bible Not Free, covers many beginner and advanced topics
A Practical Guide to Linux Commands, Editors, and Shell Programming Not Free. Focusing on practical learning with many examples
Ubuntu Pocket Guide and Reference There is a free version
Linux Bible Not Free. Covers many beginner and also advanced topics
linux-training.be Free. Little bit outdated (2015)
Modern Operating Systems Not Free. Covers advanced topics. Deep dive into Linux Internals
Understanding the Linux Kernel Not Free. Advanced. Deep dive into Linux kernel
Operating Systems: Three Easy Pieces Great book on Operating System internals

Documentation

Title Comments
Man pages The online version of man command
The Linux Documentation Project pure greatness

Linux Development Books

Forums and Communities

Online Courses (Not Free)

Name Description
Linux Academy great courses. pay yearly or monthly
Udemy payment per course

Random

Name Comments
Kernel.org Linux Kernel archives
GamingOnLinux Gaming on Linux
DistroWatch Discussions and reviews of Linux distributions
DistroTest Test a distro online before actually using it
Linux From Scratch For crazy people who would like to build a custom Linux 🙂
KaliTutorials shhh...
explainshell write down a command-line to see the help text that matches each argument
Unix Philosophy Name says it all...
CommandlineFu Great command-line gems

On.NET Episode: Exploring the new Azure .NET SDKs for .NET

26 Nov 2019, 3:49 pm

In this episode, we're joined by Adrian and Alex from the Azure SDK team who have come to talk to us about the new iteration of Azure SDKs they've been working on. They'll discuss things like what's different with this batch of SDKs, support for distributed tracing, and even give us a demo of what the .NET SDK looks like.

If you liked this video and would like to see some more of our .NET content, please subscribe to our .NET Developers YouTube Channel.

Useful Links

Singly Linked List: A Python Implementation | Part 2 | __str__ Method

26 Nov 2019, 3:48 pm

In the previous post, I started by making a Node class.

I also included an __init__ method, to make it easier to instantiate Nodes, and to ensure that each Node has the same attributes.

I then created and printed a node in the following way:

my_node = SLLNode(7, None)
print("Node with value {} and next node {}.".format(my_node.value, my_node.next_node))

That worked, but wouldn't it be nice if we could do something like print(node)?

It turns out we can. We just need to define a __str__ method.

The definition looks like this:

# indented within class SLLNode
    def __str__(self):
        s = "Node with value {} and next node: {}.".format(self.value, self.next_node)
        return s

The method __str__ works under the hood when we call print(my_node) and creates a string representation of my_node.

Let's test it to make sure it's working.

my_node = SLLNode(8, None)
print(my_node)

And the output is:

Node with value 8 and next node: None.

Now, you may have noticed that there is a potential bug lurking under the surface. How will __str__() function when a Node points to another Node? Let's find out.

second_node = SLLNode(27, None)
    first_node = SLLNode(14, second_node)
    print(first_node)

Here's the output:

Node with value 14 and next node: Node with value 27 and next node: None..

Do you see what happened? It might help if I insert some extra formatting into the output, like so:

{Node with value 14 and next node: {Node with value 27 and next node: None.}.}

Turns out __str__ got called recursively; it used __str__ again and called it on the second_node. This isn't necessarily the behaviour we want, because as the list gets longer the output could be really long and cumbersome to read.

I honestly wasn't expecting this. (I did this previously in java, and it behaves a little differently in this regard).

How will we get past this bug? Stay tuned!

The code for this project is available here on GitHub. I'll be updating it gradually as I write this series. I'll be sure to commit at least as often as I post, so you can back up and see that code as it was when I published a given post.

[EDIT]: The next post is now available here. Also, it just occured to me that these posts are themselves effectively a linked list. Meta!

From custom error types to a custom error subtype

26 Nov 2019, 3:39 pm

Previously we defined our most basic custom error class that extends the Javascript's Error prototype:

class MyError extends Error {
  constructor(message) {
    super(message)
    this.name = 'MyError'
    Error.captureStackTrace(this, MyError)
  }
}

Now let's create an error subtype that will be used to indicate certain failures for a few well known HTTP response states. MyError class and error name will be renamed to a more generic name that goes along with the context of an HTTP server — HttpError.

To keep it short, we'll pick only 3 commonly encountered HTTP status codes and create custom errors for them.

constants/httpResponseCodes.js

module.exports = {
    BAD_REQUEST: 400,
    NOT_FOUND: 404,
    INTERNAL_SERVER_ERROR: 500,
}

utils/errors.js

const responseCodes = require('../constants/httpResponseCodes.js')

class HttpError extends Error {
  constructor({ message, name, statusCode, data }) {
    super(message);
    this.name = name;
    this.statusCode = statusCode;
    this.data = data;
    Error.captureStackTrace(this, HttpError);
  }
}

class HttpBadRequest extends HttpError {
  constructor(message = 'Bad request', data) {
    super({
      message,
      name: "HttpBadRequest",
      statusCode: responseCodes.BAD_REQUEST,
      data
    });
  }
}

class HttpNotFound extends HttpError {
  constructor(message = 'Not Found', data) {
    super({
      message,
      name: "HttpNotFound",
      statusCode: responseCodes.NOT_FOUND,
      data
    });
  }
}

class HttpInternalServerError extends HttpError {
  constructor(message = 'Internal server error', data) {
    super({
      message,
      name: "HttpInternalServerError",
      statusCode: responseCodes.INTERNAL_SERVER_ERROR,
      data
    });
  }
}

module.exports = {
  HttpError,
  HttpBadRequest,
  HttpNotFound,
  HttpInternalServerError
}

We now have our custom error types and their subtype(HttpError), that will allow us to handle all of them in a generic way in the following post. A lot of code could be stripped down by using prototypal inheritance at a lower level. But it's not such a problem even if so verbose, it's very easy to follow through and the code probably won't change much once it's finished. There are libraries out there that make creating custom errors easier, but I like to have such a crucial part of the service completely independent and understandable.

Matt's Tidbits #44 - How to take great screenshots on Android

26 Nov 2019, 3:25 pm

Last time I wrote about using your phone’s sensors to add powerful behavior to your app. This week, I want to share a tip on how to take great screenshots on Android.

Yesterday, a coworker asked me how to take a screenshot on Android devices. Google’s official instructions say you should either:

  • Press and hold the power button down until a “Screenshot” button appears, which you can tap to capture one.
  • Press and hold the power and volume down buttons at the same time for a few seconds.

https://support.google.com/android/answer/9075928

It’s good to remember that this button combination may be different for different devices. And, you can always capture screenshots via Logcat within Android Studio too:
https://developer.android.com/studio/debug/am-screenshot

All of that being said, if you’re wanting to use these for presentation purposes, it can be difficult to make the screenshots look consistent, especially if you’re taking them over a period of time. Plus, nobody wants to see how many app updates or text messages you have in your screenshots.

Thankfully for us, Android has a “demo mode” which, with a few terminal commands, allows you to enforce a consistent and stripped down toolbar.

This article did a particularly good job of explaining how to make this happen:
https://android.jlelse.eu/clean-your-status-bar-like-a-pro-76c89a1e2c2f

The official documentation on using demo mode is available here:
https://android.googlesource.com/platform/frameworks/base/+/master/packages/SystemUI/docs/demo_mode.md

What useful protocols do you follow when taking screenshots? Share in the comments below! And, please follow me on Medium if you’re interested in being notified of future tidbits.

Interested in joining the awesome team here at Intrepid? We’re hiring!

This tidbit was originally delivered on March 1, 2019.

How do you stay focused in a distracted world?

26 Nov 2019, 3:20 pm

Photo: Sisyphus trying to read all its notifications

I often feel that the hardest part of my programming life is to stay focused in a distracted world.

  • Facebook, Twitter and a whole industry is working hard and smart to make us Hooked notifications junkies
  • Group Chat is making me sweat
  • Most of us are still working in Open Offices despite studies clearly pointing out that it's a false good idea.
  • There are so much cool tools I could try out
  • There are so much projects I could launch

How well do you cope with all of this?

Personally I have tried a lot things, and they help, but it still feels like a never ending battle.

Credits: The title is inspired by Cal Newport book

Deep Work: Rules for Focused Success in a Distracted World

Thanks for reading and sharing your thoughts.

If you feel like it, please help me choose what I should write next.

Open / Closed Principle

26 Nov 2019, 3:19 pm

The open closed principle is the O in the SOLID principles. It was created by Bertrand Meyer and states:

Software entities should be open for extension, but closed for modification

Let's dive deeper with an example.

We've been tasked with creating a platform that merges all video streaming sites. The platform will be able to add a platform to its list of platforms, search for a video on all platforms and play a video from the search results. The class can look like so:

CentralVideoStreamingPlatform covers most mainstream video streaming platforms. However, if we were to add another platform, say DisneyPlus, another #add() would be created. This directly violates the open for extension aspect of OCP.CentralVideoStreamingPlatform must be open to accept different details without needing to change code that's already written. By overloading #add() again, we are needlessly changing CentralVideoStreamingPlatform. Who's to say how many #add() CentralVideoStreamingPlatform would have as more streaming platforms are added?

To ensure CentralVideoStreamingPlatform's extensibility, we can refactor the video streaming classes to implement a VideoStreamingPlatform interface and use one #add().

In Conclusion

The open closed principle is a great principle to keep in mind when writing classes.

How to setup Tailwind CSS with Parcel Bundler

26 Nov 2019, 3:17 pm

Introduction

Hi all, this is Adi. Today, I wanted to share with you my experience of how I set up Tailwind CSS with Parcel Bundler, if this interests you continue reading.

I am a long time fan of Bootstrap since version 2, I have used it on nearly all my projects. Bootstrap 4 introduced many new utility classes that have made my life a little easier and my markup more readable. But lately, I have been hearing so much about the brand new CSS framework named Tailwind CSS. I am quite confident that you might have heard about it as well. So I decided to give it a try, I read through their documentation and it was as though it was made for me (this framework is so generic, it will feel the same for anyone 😂).

First I tried it with the hosted version of the framework, it has so much flexibility. Now I wanted to take it a set further and see how I could set it up in my development flow. This is where things proved tricky. Their documentation had instructions for Webpack, Gulp, Laravel Mix and a bunch of other JS tools but not for the one I use Parcel Bundler. It took me a while before I could get Tailwind to work with my existing Parcel setup.

Source Code Here

My Setup

First, let's add the new dev dependencies to your package.json file, you need parcel-bundler, postcss-modules and tailwindcss. Postcss is a css per-processor which Tailwind is built with.

Step 1
Next, create postcss.config.js in your project root file. This is the configuration for Postcss module, this will be used by Parcel during build. Also, if the NODE_ENV is set to production, we use purgecss module to compress and just have the classes we use in our markup, this process drastically reduces the final css file. This config is enough for us to get started. If you want to customize Tailwind refer to this page.

Step 2

Usage in Markup

In our html markup file, let's include css file. You'll notice that extension is .pcss this indicates Parcel Bundler to process that file with Postcss module. This file extension will be renamed to .css during the build process.

Step 3
In your app.pcss file include these three lines, this will include Tailwinds css classes, you can write normal css below these lines, that will also be included in the build output.

Step 4

Conclusion

Tailwind has been growing on me, I am just getting used to its paradigm but I can see myself use it on my future work. That's about it, if you face any issues with this configuration, please comment, I will try to help.

That’s all for now, this has been Adi.

If you need a Freelance Developer with Laravel knowledge you can contact me.

Thanks for reading.

JavaScript Errors: An Exceptional History - Part II

26 Nov 2019, 3:05 pm

Hello again! Welcome to the finalé of a two-part series of posts on errors in JavaScript.

Last time, we took a look into the history of errors in JavaScript — how JavaScript shipped without runtime exceptions, how error handling mechanisms were later added both to the fledgeling web browsers of the day and to the ECMAScript spec, and how they future efforts to standardise these features would be connected to the politics of the browser wars of the late 90's and 2000's.

This time, we'll focus a little more on the state of affairs in JavaScript today. We'll look at the different ways you can handle errors in your app today, the various idiosyncrasies they have, and how you can use our JavaScript client library to report errors from your app to our dashboard.

Let's do it!

Handling Errors Today

After the last post, you may be forgiven for thinking that handling errors gracefully in JavaScript might be a bit of a nightmare. Luckily, it's not so daunting a prospect as it might seem, but there are quite a few different ways to handle errors with varying levels of scope and different use cases.

window.onerror Handler

The window.onerror handler exists today in all modern web browsers as a means to catch uncaught exceptions from the current window. Any thrown error that is not otherwise handled in a try/catch block will be passed to the handler as the first argument to that function. The current window refers to the current global context, so it's important to note that <iframe>s and Web Workers (for example) will have their own window context.

When we use a window in the following examples, we're referring to the global window context of the browser.

By assigning a function to window.onerror, we can write custom logic to handle any uncaught exceptions that are thrown during the lifecycle of our application:

// NOTE: using typescript syntax here in order to show what types the arguments are

function onError(msg: string | Event, source?: string, lineno?: number, colno?: number, error?: Error) {
// error handling code here!
}

window.onerror = onError;

You might notice that some of these arguments are marked as optional. This is because, as you might guess, browsers disagree on the number of arguments passed to the onError handler. Browsers as recent as Safari 9, for example, do not pass an Error object as its fifth argument. Internet Explorer 9 passes neither the colno or error arguments. Because of this inconsistency, care needs to be taken when writing an onError handler that works in older browsers.

However, thanks to the existence of the Error object in most modern browsers, you can normally rely on that 5th argument to be present, which will include some useful information that might come in handy when debugging, such as the current stack trace (error.stack).

As this handler tends to be a little noisy (thanks, browser extensions...), the AppSignal JavaScript library doesn't automatically catch exceptions passed to the window.onerror handler. Instead, we have packaged this functionality in an optional plugin — the @appsignal/plugin-window-events package on npm.

As a convenience, once the onError handler is called, most browsers will call console.error behind the scenes to display the Error object (often including its stacktrace) in the console.

The Document Object Model Level 2 specification introduced the EventTarget interface to provide a generic way to bind event listeners to an Element (or other objects like Document and Window) that worked cross-browser, but also added features like the ability to have multiple handlers bound to an event. This means that many of the older event handlers, such as our friend onError, received a modern facelift.

window.addEventListener("error", function(event) {
  // error handling code here!
});

In this example, you can see that the event of type ErrorEvent is passed as the single argument to your callback. The event object contains both the information about the error but also the event itself, but again, older browsers differ in the information they provide in the event.

try/catch Operator

For synchronous code, the humble try/catch operator remains the most common way to handle exceptions. As we discussed in the previous post, try/catch exception handling allows you to try executing a block of code that may throw errors at runtime; if it does, the exception is then caught by the catch block, allowing us to control what happens and what state our app is left in.

While it's certainly true that JavaScript still allows you to throw any value as an exception, community convention has filled the gap where the ECMAScript specification leaves ambiguity; it is more commonplace to receive Error objects as the argument to the catch block nowadays, and good library implementors will generally throw Error objects for you to handle.

try {
  throw new Error("I'm broken");
  // generates an exception
} catch (e) {
  // statements to handle any exceptions
} finally {
  // clean up
}

In the catch block, you should add any code that allows you to put your app back into a defined state.

React's documentation for their Error Boundaries feature explains the problem well from a UI perspective, and the same is also true for exception handling as a whole:

For example, in a product like Messenger leaving the broken UI visible could lead to somebody sending a message to the wrong person. Similarly, it is worse for a payments app to display the wrong amount than to render nothing.

It's also a good idea to log your exception somewhere — failing silently is rarely useful, your aim here is to surface the exception as best as you can to debug problems before they become a problem for the user.

In your code, the catch block is where you would want to include your call to appsignal.sendError() if you're using our JavaScript library. Here, you can pass the Error object as an argument and have it appear in your Errors dashboard.

The finally block tends to not be as useful in JavaScript as it is in other languages. In the finally block, normally should try to clean-up any resources created before the exception was thrown, however as JavaScript is a garbage-collected language and resources are allocated and de-allocated dynamically, we often don't have to think about this much. There are times where this can be useful, however, such as for closing open connections to remote services regardless of whether the request to it was successful or not.

Promises and Async JavaScript

Admittedly, in our last post, we might have seemed a little negative about the design of JavaScript as a language. While it's almost certainly true that a lot of mistakes were made — and thanks to the ever-present need for backwards compatibility, many of them still exist today — arguably, there has been a lot of ground covered since then to make amends, and many aspects of the original design of JavaScript still hold up well today.

One of those areas that JavaScript is great at is asynchronous programming. JavaScript is an event-driven language, which is, in its simplest terms, the means to allow code to be executed by listening for events that can be triggered based on user interaction, or even messages from other programs. This is a great fit for a language like JavaScript that is mostly found embedded in a graphical environment, where you might feasibly want to execute code based on mouse clicks, or key presses.

Thanks to JavaScript's Event Loop (a concept we'll cover in full in a later edition of JavaScript Sorcery) and recent developments in the language, JavaScript lets you define points in your program where the flow of execution can be returned to the program in lieu of a value, allowing the rest of your program to run and the UI to update, and the value to the latter be filled later. We call these values Promises.

Promises themselves can contain exceptions, which when they are thrown, cause the Promise to become rejected. Once rejected, a Promise can execute a user-defined callback that we chain to it using .catch.

// You can catch errors asynchronously by listening to Promises...
asyncActionThatReturnsAPromise().catch(error => appsignal.sendError(error));

Errors can also be caught in the onRejected handler, a second parameter to .then that takes a function.

asyncActionThatReturnsAPromise().then(onFulfilled, onRejected):

The first argument to the .catch callback will normally be an Error object, but just like the try/ catch statements above, there is no explicit rule about what kind of value a Promise can be rejected with and thus passed to the .catch callback. It could technically be any value. We recommend that, when writing your own Promises, you do yourself and any future developers using your code the courtesy to reject Promises with Error objects.

Any Promises that become rejected that don't have a callback bound to the .catch handler will instead fire a callback on the window object called onunhandledrejection.

window.onunhandledrejection = function(e) {
  // error handling code here!
}

Recently, the ECMAScript standard was amended to add the async/await keywords. With these keywords, we can write async code that looks like synchronous code by using the await keyword within an async function to denote to the program that it should pause execution of the async function and wait for a value that a Promise is fulfilled with.

As we can use async/ await and async functions to write code that looks like it's synchronous even though it's not, then it's sensible to expect that we can also use the try/catch statement to handle exceptions within them, and in fact, we can!

// ...or by using async/await
async function() {
  try {
    const result = await asyncActionThatReturnsAPromise();
  } catch (error) {
    appsignal.sendError(error);
    // handle the error
  }
}

C’est tout!

That's all we have for this week!

Don't forget: our JavaScript integration was released recently and we'd love for you to give it a try in your front-end applications and tell us what you think.

If you liked this post, subscribe to our new JavaScript Sorcery list for a monthly deep dive into more magical JavaScript tips and tricks.

Try 5 scope function in kotlin

26 Nov 2019, 3:00 pm

with

When we should use this? with function use for call multiple different methods on the same object. Instead we use repetition to call variable or function in that object on every line, we can use with function. This function categories as normal function and not extensions function type, and the the last expression contain returns statement as a result. You should aware if this object contain null it will be trigger NPE, because this function never check for nullability.
You can direct call the function or variable in that object without it keyword. with function cannot add argument in their block statement because it mimic as argument instead object reference, and when if you not define the return value in the last expression, the result type will be unit/void type.

val product = Product()
with(product) {
change -> //this argument will be error or invalid
        productId = 1
        nameOfProduct = "Smartphone"
//You can add at last line with the variable type as the return value.
    }

let

When we should use this? let function use for you want to define a variable for specific scope to your code. let will invoked as parameter and returns the result of the lambda expression. Specific scope will only cover in your object that contain let function. i always use for checking nullability if the current object is null or not. This object never change the out of current object properties, only change in the scope. You should type it keyword to obtain the variable and add explicity return value in last statement to become result value or if you not do this it will be unit as the type.

val product = Product()
 product.let { 
        it.productId = 1
        it.nameOfProduct = "Smartphone"
//You can add at last line with the variable type as the return value.
    }
val product = Product()
 product.let { currentProduct ->
        currentProduct.productId = 1
        currentProduct.nameOfProduct = "Smartphone"
//You can add at last line with the variable type as the return value.
    }

run

When we should use this? run function is like combination of with and let. it have null checking so if the object is null the the block statement will never execute, and same as with function that can call multiple different method or variable in the same object. it keyword never supported in run function, instead use it keyword run function will use this operator. You can add this operator explicit or not, for call the variable/method inside that object.
Passing argument as lambda expression cannot be used in run function. Then same as let or with you must explicit add return value in the last statement to get the result type.

val product = Product()
product.run {
currentProduct -> //this argument will be error or invalid
        productId = 1
        nameOfProduct = "Smartphone"
//You can add at last line with the variable type as the return value.

    }
val product = Product()
product.run {
        this.productId = 1
        this.nameOfProduct = "Smartphone"
//You can add at last line with the variable type as the return value.

    }

also

When we should use this? also it will pass the object as parameter with return the same original object type. When you try to change in type in last statement based on the scope the return will be same as original object, so the atribute that you change in the scope will never applied for the current object type. also can use passing by argument in lambda expression so you can passing argument on this function as well. These function can use it operator, so if there pass argument by lambda expression the it operator will work.

val product = Product()
product.also {
        it.nameOfProduct = "Smartphone"
        it.productId = 1
//The return value remain product
    }
val product = Product()
product.also { currentProduct ->
        currentProduct.nameOfProduct = "Smartphone"
        currentProduct.productId = 1
//The return value remain product
    }

apply

When we should use this? apply its different from other function, that function is like extensions function type. it will run on the object reference or the receiver into expression and return the same original object type. You should notice about it keyword that not allowed in this function, instead use it, apply use this keyword. this keyword as a argument and as a return value. You dont need explicit add this operator to call the variable object just direct call the variable inside that object.

val product = Product()
product.apply {
currentProduct -> //this argument will be error or invalid
        productId = 1
        nameOfProduct = "Lipstik"
    }
product.apply {
        this.productId = 1
        this.nameOfProduct = "Lipstik"
    }

kotlin function image

Page processed in 7.356 seconds.

Leave a Reply

Your email address will not be published. Required fields are marked *