Getting started with the Twitter API may seem a bit complicated, but it’s actually quite straightforward. There are a number of libraries for common languages that make the process quite easy. Twitter’s API documentation has also improved greatly over time.
In March 2013, Twitter began requiring OAuth for all API sessions, and that’s led to improvements for users and developers all round. OAuth’s secure authenticated platform has helped Twitter protect user privacy while improving tracking; this in turn has allowed the company to increase the limits for developers on individual API calls.
This series consists of three parts. Part one will cover:
Birdcage, our basic Yii Twitter application used in this tutorial, is available to you via open source. If you’d like to learn more about Yii, check out Introduction to the Yii Framework.
Part two of this series will cover:
Part three will cover use of the real time Twitter Streaming API and the open source Phirehose streaming implementation. While part two processes tweets using the REST API, part three will describe how to build an always-on connection with the Twitter data stream. This may be a new topic for many PHP developers.
For the most part, this series of tutorials will focus on three parts of the Twitter platform:
You can read the Twitter API documentation here.
As of version 1.1, the Twitter API now requires OAuth authentication, either application-only authentication or application-user authentication. The latter requires your Twitter user to click through to the Twitter website, sign in with their credentials, and then return to your site. Application-user authentication is required for many user-specific API calls.
In other words, when you begin to access the Twitter API on behalf of a user, your user will be directed to Twitter to authorize your application. Twitter will return tokens which do not expire until the user revokes them. You’ll use these tokens to authenticate your calls on behalf of this user.
The most common way to access Twitter data is through the REST API. Using the secure tokens obtained via OAuth, your application makes requests to Twitter for specific data, e.g. the user's home timeline or their own statuses, or a request to post a tweet for a specific user.
The REST API should meet the needs of most Twitter application programmers.
The Twitter Streaming API allows you to receive tweets and notifications in real time from Twitter. However, it requires a high-performance, persistent, always-on connection between your server and Twitter.
Fortunately, there is a great open-source library called Phirehose by Fenn Bailey which implements most of the Twitter streaming API requirements. We'll review how to set up Phirehose and adapt it to your application in part three of this tutorial.
There are three variations of the Twitter Streaming API:
The job of your streaming implementation is to log the incoming events as quickly as possible and process them in the background using the REST API as necessary to harvest deeper data. Twitter sometimes calls this gathering of deeper data about events "hydrating".
Use of the REST API is subject to various rate limits by Twitter. It’s important to be a responsible user of Twitter’s API by planning limits to your activity within your application and monitoring the API rate limit responses. The Streaming API doesn't have rate limits since data is pushed to your server as it comes in.
While Twitter from a distance seems simple, it’s actually a very deep and complex data stream including the always growing timeline, relationships between users, mentions, notifications, favorites, lists, geolocation, multimedia, places, et al.
As a developer you have to decide which of this data is most important to your application to store in your own database. A minimalist approach may serve you well. The Twitter API is flexible enough that you can always go back and expand (or hydrate) the data related to the events you store.
Birdcage is a free, open-source, Yii-based application which implements the Twitter API framework for the purposes of this tutorial. If you're not familiar with Yii, please read my Introduction to the Yii Framework. Even if you're unfamiliar with Yii, the individual PHP code segments in this tutorial should be quite easy to follow.
If you wish to see a Twitter API implementation in basic PHP, check out Adam Greene's 140Dev. He's done a great job providing a basic platform for Twitter API access. His book Twitter API Engagement Programming has a creative take on using the Twitter API to organically build your influence on Twitter.
One of the benefits of Birdcage and the Yii Framework code is that we can use Yii's scaffolding component, Gii, to generate a web user interface for the basic application in minutes—something that you just can't do in basic PHP.
As a Yii application, Birdcage uses ActiveRecord database migrations to build its database. Database migrations make it possible to programmatically build and extend our schema. This is especially useful if you implement a minimalist consumption of the Twitter API and later choose to expand what you gather.
I'll walk you through several examples of constructing the database schema in Yii and the power of its web-based scaffolding constructor, Gii.
If you'd like to try out the Birdcage code on your own, please visit my site for a complete walk-through of installation instructions.
First, we’ll create an account table to store the OAuth tokens and secrets from Twitter for the accounts we wish to log in for. These accounts are linked to the registered user in the user table by our internal user_id
.
From the command line, we'll tell Yii to create a new table migration for Twitter accounts: ./app/protected/yiic migrate create create_account_table
.
We'll complete the migration manually like this:
<?php class m140911_212834_create_account_table extends CDbMigration { protected $MySqlOptions = 'ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_unicode_ci'; public $tablePrefix; public $tableName; public function before() { $this->tablePrefix = Yii::app()->getDb()->tablePrefix; if ($this->tablePrefix <> '') $this->tableName = $this->tablePrefix.'account'; } public function safeUp() { $this->before(); $this->createTable($this->tableName, array( 'id' => 'pk', 'user_id' => 'integer default 0', 'screen_name' => 'string NOT NULL', 'oauth_token' => 'string NOT NULL', 'oauth_token_secret' => 'string NOT NULL', 'last_checked' => 'TIMESTAMP DEFAULT 0', 'created_at' => 'DATETIME NOT NULL DEFAULT 0', 'modified_at' => 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP', ), $this->MySqlOptions); $this->addForeignKey('fk_account_user', $this->tableName, 'user_id', $this->tablePrefix.'users', 'id', 'CASCADE', 'CASCADE'); } public function safeDown() { $this->before(); $this->dropForeignKey('fk_account_user', $this->tableName); $this->dropTable($this->tableName); } }
To have Yii run the migration which will construct the SQL table, we do this: ./app/protected/yiic migrate up
.
You'll see something like this:
We can use Gii, Yii's web-based scaffolding generator, to build our model view controllers for the database.
In my development environment, I point my web browser to localhost:8888/twitter/app/gii
, type in my Gii password (stored in my twitter.ini
file), and choose Model Generator:
It only takes a second and should show this success message:
The model code Gii generates can be used to build a variety of methods related to the Account table. But Gii can also generate the beginnings of the web user interface for managing Twitter accounts.
Click on Bootstrap Generator, specify the Account model, and Gii will build out the scaffolding for your Account web user interface:
The resulting code creates a default model view controller user interface which looks something like this:
Using Yii Active Record Migrations and Gii is an extremely powerful timesaver for building out a basic web user interface. Once the default scaffolding code is in place, it's straightforward to customize and extend it.
Next, we’ll build the database tables for storing Twitter data, including our Twitter_User
and Tweet tables. Here's the Twitter_User
table:
$this->createTable($this->tableName, array( 'id' => 'pk', 'twitter_user_id' => 'bigint(20) unsigned NOT NULL', 'screen_name' => 'string NOT NULL', 'name' => 'string DEFAULT NULL', 'profile_image_url' => 'string DEFAULT NULL', 'location' => 'string DEFAULT NULL', 'url' => 'string DEFAULT NULL', 'description' => 'string DEFAULT NULL', 'followers_count' => 'int(10) unsigned DEFAULT NULL', 'friends_count' => 'int(10) unsigned DEFAULT NULL', 'statuses_count' => 'int(10) unsigned DEFAULT NULL', 'time_zone' => 'string DEFAULT NULL', 'created_at' => 'DATETIME NOT NULL DEFAULT 0', 'modified_at' => 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP', ), $this->MySqlOptions); $this->createIndex('twitter_user_id', $this->tableName , 'twitter_user_id', true);
Here's the Tweet table:
$this->createTable($this->tableName, array( 'id' => 'pk', 'account_id'=>'integer default 0', 'twitter_user_id'=>'bigint(20) unsigned NOT NULL', 'last_checked' => 'TIMESTAMP DEFAULT 0', 'tweet_id' => 'BIGINT(20) unsigned NOT NULL', 'tweet_text' => 'TEXT NOT NULL', 'is_rt' => 'TINYINT DEFAULT 0', 'created_at' => 'DATETIME NOT NULL DEFAULT 0', 'modified_at' => 'TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP', ), $this->MySqlOptions); $this->createIndex('tweet_id', $this->tableName , 'tweet_id', true); $this->addForeignKey('fk_tweet_account', $this->tableName, 'account_id', $this->tablePrefix.'account', 'id', 'CASCADE', 'CASCADE'); $this->addForeignKey('fk_tweet_user_id', $this->tableName, 'twitter_user_id', $this->tablePrefix.'twitter_user', 'twitter_user_id', 'CASCADE', 'CASCADE');
Notice that we use a foreign key relation to the TwitterUser
table. Gii smartly builds relations for us in the Tweet model:
public function relations() { // NOTE: you may need to adjust the relation name and the related // class name for the relations automatically generated below. return array( 'hashtags' => array(self::HAS_MANY, 'Hashtag', 'tweet_id'), 'mentions' => array(self::HAS_MANY, 'Mention', 'tweet_id'), 'account' => array(self::BELONGS_TO, 'Account', 'account_id'), 'twitterUser' => array(self::BELONGS_TO, 'TwitterUser', 'twitter_user_id'), 'urls' => array(self::HAS_MANY, 'Url', 'tweet_id'), ); }
Yii Active Record then automatically manages joins for us. Thus, you can reference TwitterUser properties in your queries with code such as echo $tweet->twitterUser->profile_image_url
.
In general, Birdcage is intended as a simple framework that you might expand on your own. I did not make great attempts here to minimize storage space based on Twitter size definitions or to optimize relations within the schema. I primarily designed this for personal use.
Twitter pre-parses tweets into what it calls entities, which help filter out metadata for you. These are divided into Mentions, URLs, and Hashtags.
When tweets mention other users, e.g. @tommcfarlin, Twitter provides metadata describing those mentions. Here's the schema we'll use to store them:
$this->createTable($this->tableName, array( 'id' => 'pk', 'tweet_id' => 'BIGINT(20) unsigned NOT NULL', 'source_user_id'=>'bigint(20) unsigned NOT NULL', 'target_user_id'=>'bigint(20) unsigned NOT NULL', ), $this->MySqlOptions); $this->addForeignKey('fk_mention_tweet', $this->tableName, 'tweet_id', $this->tablePrefix.'tweet', 'tweet_id', 'CASCADE', 'CASCADE');
Whenever tweets include links, Twitter provides metadata listing them. Here's the schema we'll use for storing URLs included in the tweets:
$this->createTable($this->tableName, array( 'id' => 'pk', 'tweet_id' => 'BIGINT(20) unsigned NOT NULL', 'url'=>'string NOT NULL', ), $this->MySqlOptions); $this->addForeignKey('fk_url_tweet', $this->tableName, 'tweet_id', $this->tablePrefix.'tweet', 'tweet_id', 'CASCADE', 'CASCADE');
Whenever tweets include hashtags, e.g. #php, Twitter provides metadata describing them. Here's the schema we'll use for storing hashtags included in the tweets:
$this->createTable($this->tableName, array( 'id' => 'pk', 'tweet_id' => 'BIGINT(20) unsigned NOT NULL', 'tag'=>'string NOT NULL', ), $this->MySqlOptions); $this->addForeignKey('fk_hashtag_tweet', $this->tableName, 'tweet_id', $this->tablePrefix.'tweet', 'tweet_id', 'CASCADE', 'CASCADE');
These migrations build the primary tables with which we'll store data from the Twitter API.
In the Birdcage code, you'll see that there are a variety of other migrations as well; most of these support the broader application.
You'll need to register an application with Twitter to obtain your first OAuth application keys. Visit the Twitter Developer site and click Manage Your Apps. Click Create New Apps; I call mine the Twitter Framework for Yii:
The callback URL for using Birdcage should be http://yourdomain.com/twitter/callback. This is the address that Twitter will return OAuth requests to. It's also the address in Birdcage of our Twitter controller for API calls.
During the creation process, you'll need to configure the app permissions (use read and write for Birdcage) and make notes of the application OAuth key and secret:
Here's what the API keys page will appear like. The top API key and secret will be needed to set up Birdcage initially:
Once you've added the application, you'll see it in the Twitter App menu:
Once you install the code, you'll need to initialize the MySQL database by running the migrations. I do this in two steps.
First, I run the Yii-User migration. This is an extension for Yii which manages most of my user login and registration needs:
./app/protected/yiic migrate --migrationPath=application.modules.user.migrations
The migration will ask you to create credentials for your primary user account for the web application:
Admin login [admin]: Admin email [webmaster@example.com]: Admin password [admin]:
This is the account you'll use to log into the Birdcage web application, not your Twitter account credentials.
Then, I run the rest of the migrations: ./app/protected/yiic up
.
Once you configure Birdcage, visit your site in your web browser, e.g. http://birdcage.yourdomain.com.
Once you log in, it will ask you to enter your application OAuth keys and address for the Twitter controller, e.g. http://yourdomain.com/twitter (just the controller, not the callback) shown in the above images:
Now, we're about ready to make interesting things happen.
Stay tuned for part two of this tutorial. Part two covers:
Then, in part three, we will look at using the Twitter Streaming API and the open source Phirehose streaming implementation. While part two processes tweets using the REST API, part three will describe how to build an always on connection with the Twitter data stream.
I hope you've found this useful. Please post any comments, corrections or additional ideas below. You can browse my other Tuts+ tutorials on my author page or follow me on Twitter @reifman.
Create Modern Vue Apps Using Create-Vue and Vite
/Pros and Cons of Using WordPress
/How to Fix the “There Has Been a Critical Error in Your Website” Error in WordPress
/How To Fix The “There Has Been A Critical Error in Your Website” Error in WordPress
/How to Create a Privacy Policy Page in WordPress
/WordPress Website Maintenance Guide For Beginners
/How Long Does It Take to Learn JavaScript?
/The Best Way to Deep Copy an Object in JavaScript
/Adding and Removing Elements From Arrays in JavaScript
/Create a JavaScript AJAX Post Request: With and Without jQuery
/5 Real-Life Uses for the JavaScript reduce() Method
/How to Enable or Disable a Button With JavaScript: jQuery vs. Vanilla
/How to Enable or Disable a Button With JavaScript: jQuery vs Vanilla
/Confirm Yes or No With JavaScript
/How to Change the URL in JavaScript: Redirecting
/15+ Best WordPress Twitter Widgets
/27 Best Tab and Accordion Widget Plugins for WordPress (Free & Premium)
/21 Best Tab and Accordion Widget Plugins for WordPress (Free & Premium)
/30 HTML Best Practices for Beginners
/31 Best WordPress Calendar Plugins and Widgets (With 5 Free Plugins)
/25 Ridiculously Impressive HTML5 Canvas Experiments
/How to Implement Email Verification for New Members
/How to Create a Simple Web-Based Chat Application
/30 Popular WordPress User Interface Elements
/Top 18 Best Practices for Writing Super Readable Code
/Best Affiliate WooCommerce Plugins Compared
/18 Best WordPress Star Rating Plugins
/10+ Best WordPress Twitter Widgets
/Working With Tables in React: Part Two
/Best CSS Animations and Effects on CodeCanyon
/30 CSS Best Practices for Beginners
/How to Create a Custom WordPress Plugin From Scratch
/10 Best Responsive HTML5 Sliders for Images and Text… and 3 Free Options
/16 Best Tab and Accordion Widget Plugins for WordPress
/18 Best WordPress Membership Plugins and 5 Free Plugins
/25 Best WooCommerce Plugins for Products, Pricing, Payments and More
/10 Best WordPress Twitter Widgets
1 /12 Best Contact Form PHP Scripts for 2020
/20 Popular WordPress User Interface Elements
/10 Best WordPress Star Rating Plugins
/12 Best CSS Animations on CodeCanyon
/12 Best WordPress Booking and Reservation Plugins
/12 Elegant CSS Pricing Tables for Your Latest Web Project
/24 Best WordPress Form Plugins for 2020
/14 Best PHP Event Calendar and Booking Scripts
/Getting Started With Django: Newly Updated Course
/Create a Blog for Each Category or Department in Your WooCommerce Store
/8 Best WordPress Booking and Reservation Plugins
/Best Exit Popups for WordPress Compared
/Best Exit Popups for WordPress Compared
/11 Best Tab & Accordion WordPress Widgets & Plugins
/12 Best Tab & Accordion WordPress Widgets & Plugins
1 /New Course: Practical React Fundamentals
/Preview Our New Course on Angular Material
/Build Your Own CAPTCHA and Contact Form in PHP
/Object-Oriented PHP With Classes and Objects
/Best Practices for ARIA Implementation
/Accessible Apps: Barriers to Access and Getting Started With Accessibility
/Dramatically Speed Up Your React Front-End App Using Lazy Loading
/15 Best Modern JavaScript Admin Templates for React, Angular, and Vue.js
/15 Best Modern JavaScript Admin Templates for React, Angular and Vue.js
/19 Best JavaScript Admin Templates for React, Angular, and Vue.js
/New Course: Build an App With JavaScript and the MEAN Stack
/10 Best WordPress Facebook Widgets
13 /Hands-on With ARIA: Accessibility for eCommerce
/New eBooks Available for Subscribers
/Hands-on With ARIA: Homepage Elements and Standard Navigation
/Site Accessibility: Getting Started With ARIA
/How Secure Are Your JavaScript Open-Source Dependencies?
/New Course: Secure Your WordPress Site With SSL
/Testing Components in React Using Jest and Enzyme
/Testing Components in React Using Jest: The Basics
/15 Best PHP Event Calendar and Booking Scripts
/Create Interactive Gradient Animations Using Granim.js
/How to Build Complex, Large-Scale Vue.js Apps With Vuex
1 /Examples of Dependency Injection in PHP With Symfony Components
/Set Up Routing in PHP Applications Using the Symfony Routing Component
1 /A Beginner’s Guide to Regular Expressions in JavaScript
/Introduction to Popmotion: Custom Animation Scrubber
/Introduction to Popmotion: Pointers and Physics
/New Course: Connect to a Database With Laravel’s Eloquent ORM
/How to Create a Custom Settings Panel in WooCommerce
/Building the DOM faster: speculative parsing, async, defer and preload
1 /20 Useful PHP Scripts Available on CodeCanyon
3 /How to Find and Fix Poor Page Load Times With Raygun
/Introduction to the Stimulus Framework
/Single-Page React Applications With the React-Router and React-Transition-Group Modules
12 Best Contact Form PHP Scripts
1 /Getting Started With the Mojs Animation Library: The ShapeSwirl and Stagger Modules
/Getting Started With the Mojs Animation Library: The Shape Module
/Getting Started With the Mojs Animation Library: The HTML Module
/Project Management Considerations for Your WordPress Project
/8 Things That Make Jest the Best React Testing Framework
/Creating an Image Editor Using CamanJS: Layers, Blend Modes, and Events
/New Short Course: Code a Front-End App With GraphQL and React
/Creating an Image Editor Using CamanJS: Applying Basic Filters
/Creating an Image Editor Using CamanJS: Creating Custom Filters and Blend Modes
/Modern Web Scraping With BeautifulSoup and Selenium
/Challenge: Create a To-Do List in React
1 /Deploy PHP Web Applications Using Laravel Forge
/Getting Started With the Mojs Animation Library: The Burst Module
/10 Things Men Can Do to Support Women in Tech
/A Gentle Introduction to Higher-Order Components in React: Best Practices
/Challenge: Build a React Component
/A Gentle Introduction to HOC in React: Learn by Example
/A Gentle Introduction to Higher-Order Components in React
/Creating Pretty Popup Messages Using SweetAlert2
/Creating Stylish and Responsive Progress Bars Using ProgressBar.js
/How to Make a Real-Time Sports Application Using Node.js
/Creating a Blogging App Using Angular & MongoDB: Delete Post
/Set Up an OAuth2 Server Using Passport in Laravel
/Creating a Blogging App Using Angular & MongoDB: Edit Post
/Creating a Blogging App Using Angular & MongoDB: Add Post
/Introduction to Mocking in Python
/Creating a Blogging App Using Angular & MongoDB: Show Post
/Creating a Blogging App Using Angular & MongoDB: Home
/Creating a Blogging App Using Angular & MongoDB: Login
/Creating Your First Angular App: Implement Routing
/Persisted WordPress Admin Notices: Part 4
/Creating Your First Angular App: Components, Part 2
/Persisted WordPress Admin Notices: Part 3
/Creating Your First Angular App: Components, Part 1
/How Laravel Broadcasting Works
/Persisted WordPress Admin Notices: Part 2
/Create Your First Angular App: Storing and Accessing Data
/Persisted WordPress Admin Notices: Part 1
/Error and Performance Monitoring for Web & Mobile Apps Using Raygun
/Using Luxon for Date and Time in JavaScript
7 /How to Create an Audio Oscillator With the Web Audio API
/How to Cache Using Redis in Django Applications
/20 Essential WordPress Utilities to Manage Your Site
/Introduction to API Calls With React and Axios
/Beginner’s Guide to Angular 4: HTTP
/Rapid Web Deployment for Laravel With GitHub, Linode, and RunCloud.io
/Beginners Guide to Angular 4: Routing
/Beginner’s Guide to Angular 4: Services
/Beginner’s Guide to Angular 4: Components
/Creating a Drop-Down Menu for Mobile Pages
/Introduction to Forms in Angular 4: Writing Custom Form Validators
/10 Best WordPress Booking & Reservation Plugins
/Getting Started With Redux: Connecting Redux With React
/Getting Started With Redux: Learn by Example
/Getting Started With Redux: Why Redux?
/Understanding Recursion With JavaScript
/How to Auto Update WordPress Salts
/How to Download Files in Python
/Eloquent Mutators and Accessors in Laravel
1 /10 Best HTML5 Sliders for Images and Text
/Site Authentication in Node.js: User Signup
/Creating a Task Manager App Using Ionic: Part 2
/Creating a Task Manager App Using Ionic: Part 1
/Introduction to Forms in Angular 4: Template-Driven Forms
/24 Essential WordPress Utilities to Manage Your Site
/25 Essential WordPress Utilities to Manage Your Site
/Get Rid of Bugs Quickly Using BugReplay
1 /Manipulating HTML5 Canvas Using Konva: Part 1, Getting Started
/10 Must-See Easy Digital Downloads Extensions for Your WordPress Site
/22 Best WordPress Booking and Reservation Plugins
/Understanding ExpressJS Routing
/15 Best WordPress Star Rating Plugins
/Creating Your First Angular App: Basics
/Inheritance and Extending Objects With JavaScript
/Introduction to the CSS Grid Layout With Examples
1Performant Animations Using KUTE.js: Part 5, Easing Functions and Attributes
Performant Animations Using KUTE.js: Part 4, Animating Text
/Performant Animations Using KUTE.js: Part 3, Animating SVG
/Performant Animations Using KUTE.js: Part 2, Animating CSS Properties
/Performant Animations Using KUTE.js: Part 1, Getting Started
/10 Best Responsive HTML5 Sliders for Images and Text (Plus 3 Free Options)
/Single-Page Applications With ngRoute and ngAnimate in AngularJS
/Deferring Tasks in Laravel Using Queues
/Site Authentication in Node.js: User Signup and Login
/Working With Tables in React, Part Two
/Working With Tables in React, Part One
/How to Set Up a Scalable, E-Commerce-Ready WordPress Site Using ClusterCS
/New Course on WordPress Conditional Tags
/TypeScript for Beginners, Part 5: Generics
/Building With Vue.js 2 and Firebase
6 /Essential JavaScript Libraries and Frameworks You Should Know About
/Vue.js Crash Course: Create a Simple Blog Using Vue.js
/Build a React App With a Laravel RESTful Back End: Part 1, Laravel 5.5 API
/API Authentication With Node.js
/Beginner’s Guide to Angular: HTTP
/Beginner’s Guide to Angular: Routing
/Beginners Guide to Angular: Routing
/Beginner’s Guide to Angular: Services
/Beginner’s Guide to Angular: Components
/How to Create a Custom Authentication Guard in Laravel
/Learn Computer Science With JavaScript: Part 3, Loops
/Build Web Applications Using Node.js
/Learn Computer Science With JavaScript: Part 4, Functions
/Learn Computer Science With JavaScript: Part 2, Conditionals
/Create Interactive Charts Using Plotly.js, Part 5: Pie and Gauge Charts
/Create Interactive Charts Using Plotly.js, Part 4: Bubble and Dot Charts
/Create Interactive Charts Using Plotly.js, Part 3: Bar Charts
/Awesome JavaScript Libraries and Frameworks You Should Know About
/Create Interactive Charts Using Plotly.js, Part 2: Line Charts
/Bulk Import a CSV File Into MongoDB Using Mongoose With Node.js
/Build a To-Do API With Node, Express, and MongoDB
/Getting Started With End-to-End Testing in Angular Using Protractor
/TypeScript for Beginners, Part 4: Classes
/Object-Oriented Programming With JavaScript
/10 Best Affiliate WooCommerce Plugins Compared
/Stateful vs. Stateless Functional Components in React
/Make Your JavaScript Code Robust With Flow
/Build a To-Do API With Node and Restify
/Testing Components in Angular Using Jasmine: Part 2, Services
/Testing Components in Angular Using Jasmine: Part 1
/Creating a Blogging App Using React, Part 6: Tags
/React Crash Course for Beginners, Part 3
/React Crash Course for Beginners, Part 2
/React Crash Course for Beginners, Part 1
/Set Up a React Environment, Part 4
1 /Set Up a React Environment, Part 3
/New Course: Get Started With Phoenix
/Set Up a React Environment, Part 2
/Set Up a React Environment, Part 1
/Command Line Basics and Useful Tricks With the Terminal
/How to Create a Real-Time Feed Using Phoenix and React
/Build a React App With a Laravel Back End: Part 2, React
/Build a React App With a Laravel RESTful Back End: Part 1, Laravel 9 API
/Creating a Blogging App Using React, Part 5: Profile Page
/Pagination in CodeIgniter: The Complete Guide
/JavaScript-Based Animations Using Anime.js, Part 4: Callbacks, Easings, and SVG
/JavaScript-Based Animations Using Anime.js, Part 3: Values, Timeline, and Playback
/Learn to Code With JavaScript: Part 1, The Basics
/10 Elegant CSS Pricing Tables for Your Latest Web Project
/Getting Started With the Flux Architecture in React
/Getting Started With Matter.js: The Composites and Composite Modules
Getting Started With Matter.js: The Engine and World Modules
/10 More Popular HTML5 Projects for You to Use and Study
/Understand the Basics of Laravel Middleware
/Iterating Fast With Django & Heroku
/Creating a Blogging App Using React, Part 4: Update & Delete Posts
/Creating a jQuery Plugin for Long Shadow Design
/How to Register & Use Laravel Service Providers
2 /Unit Testing in React: Shallow vs. Static Testing
/Creating a Blogging App Using React, Part 3: Add & Display Post
/Creating a Blogging App Using React, Part 2: User Sign-Up
20Creating a Blogging App Using React, Part 1: User Sign-In
/Creating a Grocery List Manager Using Angular, Part 2: Managing Items
/9 Elegant CSS Pricing Tables for Your Latest Web Project
/Dynamic Page Templates in WordPress, Part 3
/Angular vs. React: 7 Key Features Compared
/Creating a Grocery List Manager Using Angular, Part 1: Add & Display Items
New eBooks Available for Subscribers in June 2017
/Create Interactive Charts Using Plotly.js, Part 1: Getting Started
/The 5 Best IDEs for WordPress Development (And Why)
/33 Popular WordPress User Interface Elements
/New Course: How to Hack Your Own App
/How to Install Yii on Windows or a Mac
/What Is a JavaScript Operator?
/How to Register and Use Laravel Service Providers
/
waly Good blog post. I absolutely love this…