Shared posts

09 Oct 06:00

‘Other’ Dark Matter

by John Gruber

John Moltz, back in August:

My wife’s iPhone 5 has been complaining about space for months. To date she’d just keep reducing the amount of music she was keeping on it in order to install new apps. Finally I took a look at it yesterday. She only had two and a half pages of apps no videos and just 2 GB of music. Even on a 16 GB phone that shouldn’t fill it up.

Plugging it into her MacBook, I could see the “Other” part of the usage bar was huge, at least 2/3 of the bar if not half. So I suggested restoring it. I restored the phone to a base iOS 7.1.2 install and then restored the most recent backup in iTunes (yes, I back up to iTunes because I’m old school). If you’re going to try this, remember to select to encrypt the backup (and that you have a backup after doing that), that way you won’t have to enter all your passwords again.

I didn’t take notes of the sizes before restoring because I’m an idiot, but I can tell you she got back somewhere between 6 and 7 GB of space.

A bunch of the emails I’ve gotten today from readers who’ve struggled with the iOS 8 OTA update requiring more free storage space have mentioned this factor — “Other” consuming several gigabytes of space that gets freed up if you do a full restore. Not sure what’s going on there, but it seems like something Apple should look at.

09 Oct 05:58

Samsung’s Woes: Saved by the Chips

by John Gruber

The Economist on Samsung’s plunging profits:

Samsung seems to have a different plan, however. It is betting that its chip business, which has done well in the third quarter, will provide more of its growth. On October 6th the firm announced that it will spend nearly $15 billion on a new semiconductor plant in South Korea to meet the growing demand for processors in mobile devices. Although the decline of its smartphone business will not be an existential threat to Samsung, it remains to be seen whether making chips will replace all the profits it has lost.

Ironic in the way that Microsoft profits from Android, Samsung is a major component supplier for Apple, and thus profits from the sale of iPhones.

09 Oct 05:58

Andrew Sullivan on Revenue for Journalism

by John Gruber

Andrew Sullivan, in an interview with Capital New York:

I think the only future for journalism is reader revenue. Without it, you are in danger of becoming a public relations or advertising company disguised as journalism, like Buzzfeed and even The Guardian. Buzzfeed is really an ad agency with some journalistic window dressing. They’re not the future of journalism; they’re the marginalization of it. And The New York Times, alas, is following suit with merry abandon.

I think he’s right about Buzzfeed, but in a different way. It’s not that reader revenue is the only future for journalism. It’s that pageview-driven revenue is a corrupting force. Pageview models so dominate online advertising that many people treat them as synonymous. They’re not. There are ways to do advertising online that don’t lead to the dangerous incentives (in a word, clickbait) and reader-hostile experiences that pageviews do.

Let a thousand non-pageview-driven revenue models bloom. Direct reader contributions are working well for Sullivan’s The Dish, and that’s great. But it’s not the only way.

08 Oct 22:46

How to get a free Lego mini build every month

by Michael Schulte on LEGO, shared by Brian Barrett to Gizmodo

How to get a free Lego mini build every month

On the first Tuesday of every month, Lego brand stores do an absolutely free (no purchase required) mini model build. To get yours all you have to do is show up at the store anytime after 5:00 or 5:30 pm (check with your Lego store) and be between the ages of 6-14.

Read more...

08 Oct 22:37

Subterranean Food Court Coming To Columbus Circle Subway Station

by Nell Casey
Subterranean Food Court Coming To Columbus Circle Subway Station Above ground, the glittering Time Warner Center and its fancy shops cast their chilly shadow over Central Park; down below, commuters and tourists swirl in one of the city's busiest subway hubs, Columbus Circle. Soon, the two will merge, when a new shopping center and food court-type outlet opens below ground, offering the chance to eat and shop without having to venture into the sunlight. The Times takes a look at a forthcoming project called TurnStyle (see what they did there?) that will bring retail and restaurant outlets below ground to the IRT line. [ more › ]






08 Oct 21:49

Red Bull Will Give You Money If You Drank Red Bull in the Last 12 Years

by Hugh Merwin

You can also settle for $15-worth of Red Bull merchandise.

Because Red Bull once advertised that it "gives you wings" when it in fact does no such thing, the energy-drink-maker has now settled two class-action lawsuits and says it will mail a $10 check or send $15-worth of Red Bull to anyone who drank the stuff in the last 12 years. Claim forms can be filled out right here, but here's what you need to know: The class encompasses anyone who bought a can from January 1, 2002, right up through last Friday, October 3, and no proof of purchase is necessary for consumers to join. The proposed settlement still needs approval from the U.S. District Court of the Southern District of New York, which makes things uncertain, but the legal development could definitely turn out to be a great, if not inadvertent marketing campaign for the company.

The settlement totals more than $13 million, which is still a lot less than the cost of two 60-second Super Bowl spots. Though the class action has a long way and many details to go before it's over — the final hearing is scheduled for May 1, 2015 — it's a kind of truth-in-advertising lawsuit that strikes most people as relatively benign: Greek yogurt isn't made by Greeks in Greece; Templeton Rye isn't distilled in Templeton, Iowa; and Tito's Handmade Vodka isn't technically made by hand. That sort of thing. Moreover, the nature of the lawsuit is likely to distract some people from the more serious claims that have been associated with energy drinks in general in the last few years.

Red Bull says it "settled the lawsuit to avoid the cost and distraction of litigation" and has now "voluntarily withdrawn" the marketing claim that drinking it gives people wings. The class-action suit site has apparently crashed twice since this morning by the intense rush of consumers looking to score what amounts to a lot of money and a lot of Red Bull, however, so it may turn out that crashing is better than soaring in the long run.

[Official site, BuzzFeed]

Read more posts by Hugh Merwin

Filed Under: lawsuits, news, red bull

08 Oct 21:48

Multilayer Sensors are Coming From Canon [CR2]

by Canon Rumors
1ds

Canon has been hard at work on multi-layer sensors and they will be coming in an upcoming professional level full frame DSLR we’re told. There will be two cameras based on this technology coming in 2015, one would expect a replacement for the EOS-1D X and perhaps another professional body with a high megapixel count. There was no mention of an EOS 5D Mark IV.

The high resolution camera is expected to be announced in Q1 of 2015. Even though we have heard from places unknown that such a camera would make an appearance at PhotoPlus at the end of this month. A Canon Explorer of Light has told us they’ve been promised a high megapixel camera to come “sooner than later”.

I suspect most of this came from Photokina chatter.

cr

08 Oct 21:41

★ Note to Self: It’s the Storage Space, Stupid

by John Gruber

Last night I speculated that the slow uptake of iOS 8 was about people not trusting Apple with iOS software updates — too many bugs, and too many friends and family members talking about those bugs. I still think there’s something to that angle.

But it’s very clear that I was wrong about what the primary factor is. The simple answer was staring me right in the face. It’s all about the over-the-air update requiring 5 GB of free storage space, and many people not having that much free space, and not knowing how or simply not wanting to deal with it.

I don’t think I have ever received so much reader feedback on a post in the history of Daring Fireball. Hundreds of emails. Dozens and dozens of replies on Twitter. All of them saying the exact same thing: that either they themselves or people they know want to upgrade to iOS 8 but haven’t yet or can’t because the OTA software update won’t fit on their devices.

Jonathan Hoover puts it well:

iOS 8 OTA update requires about 5GB of free space on the device. Most people, especially those who wouldn’t update until they get the badge on the settings app, don’t have 5GB free on their iPhone. They have no idea they can plug their iPhone into their computer and iTunes will update it. They don’t know they can free up space by downloading their pictures and videos to their computer. 

iPhone makes it so easy for casual users to take gigabytes of photos and videos but nearly impossible for those users to know what to do with them.

This is a serious problem for Apple, because all those 16 GB devices (let alone the 8 GB ones) aren’t going to suddenly gain more free storage space on their own. A lot of these devices might never get updated to iOS 8, but would if the OTA software worked. Unless they can rejigger the OTA software update to require less free space, iOS 8’s adoption rate might lag permanently.1

Which in turn brings to mind one of the closing paragraphs of my review of the new iPhones 6:

But I don’t understand why the entry level storage tier remained at a meager 16 GB. That seems downright punitive given how big panoramic photos and slo-mo HD videos are, and it sticks out like a sore thumb when you look at the three storage tiers together: 32/64/128 looks natural; 16/64/128 looks like a mistake. The original iPhone, seven years and eight product generations ago, had an 8 GB storage tier. The entry-level iPhones 6 are 50 times faster than that original iPhone, but have only twice the storage capacity. That’s just wrong. This is the single-most disappointing aspect of the new phones.

iOS itself takes up about 4 GB, so these 16 GB devices only have about 12 GB free right out of the box. If there is any way that Apple could have brought the base model storage up to 32 GB with the new iPhones, they should have. And it’s inexcusable that they’re still selling new devices with only 8 GB of storage.

If this decision was made simply in the interest of profit margins, and/or to nudge would-be entry-level-model buyers to the more expensive 64 GB mid-range models, whatever money Apple is making from this is not worth it, in the long run, compared to the collective goodwill they’re losing and the frustration they’re creating.


  1. One small thing Apple could do: when alerting the user that there isn’t enough space to install the update, they could provide a link to this support article — “Resolve issues with an over-the-air iOS update” — which is actually quite helpful. 

08 Oct 18:24

Kid tapes cop smashing car window, dragging man away after tasering him

by David Kravets

A 14-year-old boy's videotape of an Indiana cop smashing an ax though a vehicle window, shooting the passenger with a stun gun, and ripping him from the vehicle has become the subject of an excessive force lawsuit.

Monday's lawsuit [PDF] is among the most recent in a wave of police encounters gone awry that have been captured on video and resulted in legal action. The incident was filmed two weeks ago in Hammond, Indiana, and it started with a motorist being stopped and pulled over for allegedly not wearing a seatbelt.

Read 8 remaining paragraphs | Comments

08 Oct 18:19

Norway's New Currency Design Is Perfectly Pixelated High-Concept Art

by Alissa Walker

Norway's New Currency Design Is Perfectly Pixelated High-Concept Art

With last week's news that Oslo had pulled out of the 2022 Winter Olympics, I got really sad—mostly that we wouldn't see the beautiful identity from the architects at Snøhetta brought to life. But here's a consolation: Snøhetta won a competition to redesign Norway's currency. And the pixelated landscapes they designed are absolutely gorgeous.

Read more...

08 Oct 17:17

Berkeley Vows Its Soda-Tax Vote Is Going to Be Big Soda’s ‘Waterloo’

by Clint Rainey

Look at all that tax revenue.

The "most contested fight" in Berkeley right now is "pitting every elected official … against the soft drink industry." Residents voted on a proposed one-cent-per-ounce soda tax in November, and taking no chances, Big Soda — which already fizzed out Michael Bloomberg, plus Maine and Texas, plus an assortment of municipalities — has plowed $1.4 million into ads and other efforts so far, dwarfing the $135,000 put up by anti-sugary-soda proponents. "If it can't pass in Berkeley, where is it going to pass?" pro-tax Mayor Tom Bates tells him. "Honest to God, if they can stop us here, they can stop us anywhere. And they know that."

There's a bolder two-cent tax proposed across the bay in San Francisco proper, but it needs a two-thirds vote to pass, so insiders have mostly written it off. "We feel pretty confident we can beat it in San Francisco," says a beverage-industry spokesman, but adds, "Berkeley is a lot tougher."

The fight there has plenty of chest-pounding. There are "Berkeley vs. Big Soda" yard signs, city officials have welcomed the entire industry to "their Waterloo," and Big Soda is dismissing Berkeley's broader political cachet in case of a loss, a place that's "not necessarily the trendsetter that they claim to be ... They give free pot to low-income folks." Mud-slinging or not, this measure is honestly probably doomed like every soda ban/warning label/tax effort before it, but that's all the more reason to choose sides, grab a water or Coke, regular or diet, sparkling or tap, and watch the returns.

Related: California's Plan to Put Obesity Warning Labels on Soda Fizzles Out

[NYT]

Read more posts by Clint Rainey

Filed Under: soda wars, berkeley, california, health concerns, news, soda tax

08 Oct 16:57

AT&T to pay $105 million for 'cramming' extra charges into customer bills

by Adi Robertson

The US government is slapping down AT&T for allowing extra charges on customers' phone bills with what it calls the "largest cramming settlement in history." The news was announced on Wednesday in a joint press conference held by the FCC, the FTC, and all state attorneys general, who worked together on the resolution. That resolution concerns what's known as "mobile cramming," in which third parties can pass charges along to phone companies for spam SMS messages or things like daily horoscopes and "fun facts." Federal investigators found that for years, AT&T made hundreds of millions of dollars by taking 35 percent of these unwanted charges, dodging complaints from customers and reassuring the companies themselves.

Continue reading…

08 Oct 16:28

Slack has a serious data leak

by Russell Brandom

Today, Valleywag uncovered a troubling data leak in the popular chat app Slack. First unearthed by developer Tanay Sai, Slack's sign-up process shows the popular rooms in a given company before a user is fully verified. That means that if you want to see what Google's working on, you can enter a dummy ____@google.com account, see what teams have set up unique accounts, and cancel the process before entering a password. In fact, Valleywag pulled off this exact trick, discovering a "Tribe Wearables" room that hints at a possible acquisition.

Continue reading…

08 Oct 16:19

Hunting for Water Leaks in California's Drought

by Sarah Zhang

Hunting for Water Leaks in California's Drought

California is wasting water, even when we don't realize it. Our aging underground water pipelines—in some cases nearly a century old—invariably spring leaks, thousands of them that add up to 23 billion gallons a year in California alone.

Read more...

08 Oct 16:14

Thomas Duncan, the first patient diagnosed with Ebola in the US, has died

by Arielle Duhaime-Ross

Thomas Duncan, the first person to be diagnosed with Ebola in the US, has died, reports The New York Times. Duncan was diagnosed with Ebola on 30 September and died just before 8AM this morning at the Texas Health Presbyterian Hospital in Dallas.

Continue reading…

08 Oct 15:55

There’s Something Going On In L.A.

by Mark Suster
LA_Beach It’s the new refrain I hear from investors and even entrepreneurs these days. I hear it right after people decide to come by for a few days to “check out what all the fuss is about.” I hear it when I visit LPs (the people who invest in VCs) all across the country, “Yeah, I haven’t been out there for a few years but I keep hearing that something is going on… Read More
08 Oct 15:53

Red Bull Class Action Settlement

by Jonathan Ping

Red Bull has settled a lawsuit alleging that their marketing and labeling misrepresents both the functionality and safety of Red Bull beverages. The Settlement Class includes all persons who made at least one purchase of Red Bull products in the United States between January 1, 2002 and October 3, 2014. If you are a qualified Settlement Class Member and submit a Claim Form, you may choose one of the following:

  • A cash reimbursement (in the form of a check) of $10.00; or
  • Free Red Bull products (either Red Bull ® Energy Drink or Red Bull ® Sugarfree, as selected on the Claim Form) with a retail value of approximately $15.00 (the “Product Option”). They will mail it to you at their cost.

“No proof of purchase is necessary to obtain settlement benefits. However, the Claim Form must be signed by you under penalty of perjury (either by hand or, if you submit it online, electronically), affirming that you are a qualified member of the Settlement Class and that the information provided therein is true and accurate to the best of your knowledge.”

This is all taken from the official site EnergyDrinkSettlement.com. Checks probably won’t be mailed out until late 2015 at the earliest.




Red Bull Class Action Settlement from My Money Blog.


© MyMoneyBlog.com, 2014.

08 Oct 14:19

Italy’s Most Famous Chef Will Roll Out a Limited-Edition Shake Shack Burger Next Week

by Hugh Merwin

The "Emilia" is available for one day only, and there will only be 1,000 of them.

Massimo Bottura, the renowned Italian chef, is coming to town, and on Monday he'll be at Shake Shack's original Madison Square Park location, where just 1,000 of his limited-edition hamburgers will be served. In a move reminiscent of the chain's bonkers chef collaborations from the summer, Bottura collaborated with culinary director Mark Rosati on this powerhouse, which has got Parmigiano-Reggiano mixed right into the LaFrieda-blend beef, as well as two rounds of ultrapork-y cotechino, some bright salsa verde, and fancy balsamic mayo on top. Monday is also the Shack's final day in the park, it turns out, until next year.

The "Emilia" — thankfully, no one decided to name the Columbus Day special the Niña, Pinta, or Santa María — will go for $8.95 a pop, and also commemorates the last day of operations at Shake Shack before the ten-year-old kiosk closes for renovations. Edwin Bragg, a Shake Shack rep, said previously that the renovations will take approximately five months to complete. Today, Danny Meyer's restaurant group says that the location will reopen in "mid 2015."

Related: Original Shake Shack Location Will Close for 5 Months

Read more posts by Hugh Merwin

Filed Under: news, columbus day, mark rosati, massimo bottura, shack shack

08 Oct 04:41

MacRumors: ‘iOS 8 Adoption Stagnates Just Two and a Half Weeks After Launch’

by John Gruber

Juli Clover, MacRumors:

After almost three weeks of availability, Apple’s iOS 8 operating system is now installed on 47 percent of devices, according to new numbers posted on Apple’s App Store support page for developers.

That marks a very slight increase in adoption over the past two weeks, as back on September 21, iOS 8 was installed on 46 percent of devices. 47 percent of iOS users continue to stick to iOS 7, possibly due to a number of bugs that have plagued the launch of iOS 8.

Very worrisome — a canary-in-the-coal-mine indicator that casual users no longer trust Apple with major iOS updates. Last year the number for iOS 7 adoption was in the 70s in October, which was a faster adoption rate than iOS 6 the year prior.

Follow-Up:Note to Self: It’s the Storage Space, Stupid”.

08 Oct 03:47

​Warner Bros is building a holographic Batcave for the Oculus Rift

by Sean Buckley
Like comic books? Then you're probably familiar with the style of Bruce Timm, the father of the DC animated universe -- a specific era (and style) of DC Comics animation projects that started with the 1992 Batman: The Animated Series. If you missed...
08 Oct 03:17

San Francisco Legalizes, Regulates Airbnb With 7-4 Vote, Lots of Amendments

by Kim-Mai Cutler
Airbnb Symbol After six years of operating in San Francisco, Airbnb will finally become legal on its own home turf. The city’s board of supervisors voted to legalize and regulate short-term stays through a controversial piece of legislation that has been two years in the making and comes in the midst of one of the city’s most acute housing shortages in history. David Chiu, who is the president… Read More
07 Oct 21:44

Ex-BioShock Developers Are Making An Arty Version Of Oregon Trail

by Yannick LeJacq

Ex-BioShock Developers Are Making An Arty Version Of Oregon Trail

We've all heard the story many times now: talented game developers leave their corporate jobs to strike out on their own, turning to Kickstarter in the process. So what makes The Flame in the Flood stand out? Something about BioShock's art director making a modern fancified version of The Oregon Trail, if you ask me.

Read more...

07 Oct 21:05

Pete Wells Hates Restaurant Cocktails, Because They're Just to Make People Spend Money

by Marguerite Preston

The Times critic files a takedown of the state of restaurant cocktails.

Pete Wells files a long discussion today of the state of restaurant cocktails, which he says is largely dismal these days. His complaints are legion, from the proliferation of "original" cocktails, to the long lists of ingredients. But overall, the main issue seems to be that restaurants have cocktail menus at all these days, which is not, Wells says, the way it used to be.

Why is that? Eben Freeman, cocktail consultant to Michael White and AvroKo offers this disheartening explanation: "You're hoping to get a cocktail sale in before they settle down with the wine list. The dark side is that they will drink the cocktail faster...And it will affect their decision-making, and might cause them to get the steak for two. Or the more expensive bottle of wine."

But even Wells admits there are some exceptions to the rule out there, including the Nomad, and some of Michael White's restaurants. Ryan Sutton weighs in on his favorites (Carbone, Empellon Cocina, Betony to name a few) over in the forums. Feel free to do the same.

07 Oct 20:55

Sapphire company CEO sold $160,000 in stock days before iPhone 6 reveal

by Andrew Cunningham
GT's stock rode high on the iPhone rumors for months, but it dropped when the new iPhones launched without sapphire and fell down a hole when it announced the bankruptcy filing.

GT Advanced Technologies, the company Apple currently relies on for sapphire in its iOS devices, filed for Chapter 11 bankruptcy yesterday. The filing came just a few weeks after Apple announced its new iPhones on September 10—both the iPhone 6 and 6 Plus were widely expected to use sapphire instead of glass to protect their screens from scratches. This didn't happen, though, and it sent GT's stock price sliding downward even before yesterday's bankruptcy filing pushed it off a cliff.

Now The Wall Street Journal reports that GT CEO Thomas Gutierrez has sold over $10 million in stock since February of 2014, including 9,000 shares worth about $160,000 on September 8. This was two days before the iPhone announcement. The stock closed at $17.15 on the 8th, but had fallen to $12.78 on the 10th following Apple's event.

A GT filing says that the stock sale was merely coincidental, and that the stocks were being sold according to a schedule set in March of 2014. The WSJ reports "no obvious pattern to his sales."

Read 1 remaining paragraphs | Comments

07 Oct 17:53

I rode an electric unicycle through the streets of New York City and it felt like the future

by Sam Sheffer

I commute to work every day using a skateboard. I skate from my apartment to the subway, and then from the subway to work, and vice versa. It's fast and it works, but I'm still on the hunt for the best personal EV. Hell, it's almost 2015 — where's my hoverboard?

For the last week I've been living with Focus Designs' self balancing unicycle (SBU). I've been commuting to and from work with it (getting through subway turnstiles with the SBU is akin to having a small suitcase). I've taken it along the East River, to Brooklyn, over the Williamsburg Bridge, and through Central Park.

I’ve used other futuristic rideables, like the Zboard and E-Go Cruiser, but this was my first interaction with a unicycle — motorized or not. Riding the SBU...

Continue reading…

07 Oct 17:52

Make Lunch High-Stakes With "Seamless Roulette"

by Nell Casey
Make Lunch High-Stakes With "Seamless Roulette" Scrolling through Seamless's many dining options can be both an exhilarating ("It's almost lunchtime!") and frustrating ("Ugh, what do I want to eat?") experience. But if you're willing to put your mealtime fate into the hands of a computer algorithm, you can avoid the decision-making and with a few clicks have food delivered without ever having to gaze at a menu. Meet Seamless Roulette, a new site launched this morning that will deliver you food from a random restaurant nearby using your Seamless account as a guide. [ more › ]






07 Oct 16:54

Google Voice now supports MMS from most North American carriers except Verizon

by Chris Welch

It's been a long time coming, but Google Voice has now added MMS support from almost every major US carrier. Except for Verizon, that is. Your Google Voice number should now be able to receive in-line MMS photos from people on AT&T, Sprint, T-Mobile, or another of "nearly 100 different North American carriers." (In Canada, Bell Canada, Rogers, Telus, and others are playing nice with MMS / Google Voice compatibility.) "For too long, however, Google Voice users would miss these messages for lack of MMS support," wrote Googler Alex Wiesen. Thankfully that's no longer the case for most carriers, but apparently Verizon still isn't on board. The largest US carrier isn't mentioned by name as a participating partner, and Wiesen takes a...

Continue reading…

07 Oct 16:17

iOS 8 adoption slows following botched update and storage issues

by Tom Warren

iOS 8 launched almost three weeks ago, and nearly half of active iPhones, iPads, and iPod touch music players upgraded within a week of availability. While the quick adoption rate might have seemed impressive at first — especially compared to rival Android software updates — iOS 8 installs appear to have stalled significantly recently. Apple’s own App Store support page reveals that 47 percent of all active devices are running iOS 8, an increase of only one percentage point from two weeks ago.

There’s no obvious reason for the slow down in adoption, but a botched iOS 8.0.1 update may have put people off upgrading, alongside huge storage requirements for iOS 8 which have prevented many 16GB and 8GB iPhone owners from updating without...

Continue reading…

07 Oct 15:30

An Introduction To Unit Testing In AngularJS Applications

by Sébastien

AngularJS1 has grown to become one of the most popular single-page application frameworks. Developed by a dedicated team at Google, the outcome is substantial and widely used in both community and industry projects.

One of the reasons for AngularJS’ success is its outstanding ability to be tested. It’s strongly supported by Karma112 (the spectacular test runner written by Vojta Jína) and its multiple plugins. Karma, combined with its fellows Mocha173, Chai184 and Sinon205, offers a complete toolset to produce quality code that is easy to maintain, bug-free and well documented.

“Well, I’ll just launch the app and see if everything works. We’ve never had any problem doing that – No one ever.”

The main factor that made me switch from “Well, I just launch the app and see if everything works” to “I’ve got unit tests!” was that, for the first time, I could focus on what matters and on what I enjoy in programming: creating smart algorithms and nice UIs.

I remember a component that was supposed to manage the right-click menu in an application. Trust me, it was a complex component. Depending on dozens of mixed conditions, it could show or hide buttons, submenus, etc. One day, we updated the application in production. I can remember how I felt when I launched the app, opened something, right-clicked and saw no contextual menu — just an empty ugly box that was definitive proof that something had gone really wrong. After having fixed it, re-updated the application and apologized to customer service, I decided to entirely rewrite this component in test-driven development style. The test file ended up being twice as long as the component file. It has been improved a lot since, especially its poor performance, but it never failed again in production. Rock-solid code.

A Word About Unit Testing

Unit testing has become a standard in most software companies. Customer expectations have reached a new high, and no one accepts getting two free regressions for the price of one update anymore.

If you are familiar with unit testing, then you’ll already know how confident a developer feels when refactoring tested code. If you are not familiar, then imagine getting rid of deployment stress, a “code-and-pray” coding style and never-ending feature development. The best part of? It’s automatic.

Unit testing improves code’s orthogonality. Fundamentally, code is called “orthogonal” when it’s easy to change. Fixing a bug or adding a feature entails nothing but changing the code’s behavior, as explained in The Pragmatic Programmer: From Journeyman to Master6. Unit tests greatly improve code’s orthogonality by forcing you to write modular logic units, instead of large code chunks.

Unit testing also provides you with documentation that is always up to date and that informs you about the code’s intentions and functional behavior. Even if a method has a cryptic name — which is bad, but we won’t get into that here — you’ll instantly know what it does by reading its test.

Unit testing has another major advantage. It forces you to actually use your code and detect design flaws and bad smells. Take functions. What better way to make sure that functions are uncoupled from the rest of your code than by being able to test them without any boilerplate code?

Furthermore, unit testing opens the door to test-driven development. While it’s not this article’s topic, I can’t stress enough that test-driven development is a wonderful and productive way to write code.

What and What Not to Test

Tests must define the code’s API. This is the one principle that will guide us through this journey. An AngularJS application is, by definition, composed of modules. The elementary bricks are materialized by different concepts related to the granularity at which you look at them. At the application level, these bricks are AngularJS’ modules. At the module level, they are directives, controllers, services, filters and factories. Each one of them is able to communicate with another through its external interface.

Everything is bricks, regardless of the level you are at.7
Everything is bricks, regardless of the level you are at. (View large version8)

All of these bricks share a common attribute. They behave as black boxes, which means that they have a inner behavior and an outer interface materialized by inputs and outputs. This is precisely what unit tests are for: to test bricks’ outer interfaces.

Black box model (well, this one is gray, but you get the idea).9
Black box model (well, this one is gray, but you get the idea) (View large version10)

Ignoring the internals as much as possible is considered good practice. Unit testing — and testing in general — is a mix of stimuli and reactions.

Bootstrapping A Test Environment For AngularJS

To set up a decent testing environment for your AngularJS application, you will need several npm modules. Let’s take a quick glance at them.

Karma: The Spectacular Test Runner

Karma112 is an engine that runs tests against code. Although it has been written for AngularJS, it’s not specifically tied to it and can be used for any JavaScript application. It’s highly configurable through a JSON file and the use of various plugins.

If you don’t see this at some point in this process, then you might have missed something.12
If you don’t see this at some point in the process, then you might have missed something. (View large version13)

All of the examples in this article can be found in the dedicated GitHub project14, along with the following configuration file for Karma.

// Karma configuration
// Generated on Mon Jul 21 2014 11:48:34 GMT+0200 (CEST)
module.exports = function(config) {
  config.set({

    // base path used to resolve all patterns (e.g. files, exclude)
    basePath: '',

    // frameworks to use
    frameworks: ['mocha', 'sinon-chai'],

    // list of files / patterns to load in the browser
    files: [
      'bower_components/angular/angular.js',
      'bower_components/angular-mocks/angular-mocks.js',
      'src/*.js',
      'test/*.mocha.js'
    ],

    // list of files to exclude
    exclude: [],

    // preprocess matching files before serving them to the browser
    preprocessors: {
      'src/*.js': ['coverage']
    },

    coverageReporter: {
      type: 'text-summary',
      dir: 'coverage/'
    },

    // test results reporter to use
    reporters: ['progress', 'coverage'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests on file changes
    autoWatch: true,

    // start these browsers
    browsers: ['PhantomJS'],

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false
  });
};

This file can be automagically generated by typing karma init in a terminal window. The available keys are described in Karma’s documentation15.

Notice how sources and test files are declared. There is also a newcomer: ngMock16 (i.e. angular-mocks.js). ngMock is an AngularJS module that provides several testing utilities (more on that at the end of this article).

Mocha

Mocha173 is a testing framework for JavaScript. It handles test suites and test cases, and it offers nice reporting features. It uses a declarative syntax to nest expectations into cases and suites. Let’s look at the following example (shamelessly stolen from Mocha’s home page):

describe('Array', function() {
  describe('#indexOf()', function() {
    it('should return -1 when the value is not present', function() {
      assert.equal(-1, [1,2,3].indexOf(5));
      assert.equal(-1, [1,2,3].indexOf(0));
    });
  });
});

You can see that the whole test is contained in a describe call. What is interesting about nesting function calls in this way is that the tests follow the code’s structure. Here, the Array suite is composed of only one subsuite, #indexOf. Others could be added, of course. This subsuite is composed of one case, which itself contains two assertions and expectations. Organizing test suites into a coherent whole is essential. It ensures that test errors will be reported with meaningful messages, thus easing the debugging process.

Chai

We have seen how Mocha provides test-suite and test-case capabilities for JavaScript. Chai184, for its part, offers various ways of checking things in test cases. These checks are performed through what are called “assertions” and basically mark a test case as failed or passed. Chai’s documentation has more19 on the different assertions styles.

Sinon

Sinon205 describes itself as “standalone test spies, stubs and mocks for JavaScript.” Spies, stubs and mocks all answer the same question: How do you efficiently replace one thing with another when running a test? Suppose you have a function that takes another one in a parameter and calls it. Sinon provides a smart and concise way to monitor whether the function is called and much more (with which arguments, how many times, etc.).

Unit Testing At The Application Level

The point of the external interface of a module in an AngularJS application is its ability to be injected into another module — that it exists and has a valid definition.

beforeEach(module('myAwesomeModule'));

This is enough and will throw an error if myAwesomeModule is nowhere to be found.

Unit Testing At The Module Level

An AngularJS module can declare several types of objects. Some are services, while others are more specialized. We will go over each of them to see how they can be bootstrapped in a controlled environment and then tested.

Filters, Services and Factories: A Story of Dependency Injection

Filters, services and factories (we will refer to these as services in general) can be compared to static objects or singletons in a traditional object-oriented framework. They are easy to test because they need very few things to be ready, and these things are usually other services.

AngularJS links services to other services or objects using a very expressive dependency-injection model, which basically means asking for something in a method’s arguments.

What is great about AngularJS’ way of injecting dependencies is that mocking a piece of code’s dependencies and injecting things into test cases are super-easy. In fact, I am not even sure it could be any simpler. Let’s consider this quite useful factory:

angular.module('factories', [])
.factory('chimp', ['$log', function($log) {
  return {
    ook: function() {
      $log.warn('Ook.');
    }
  };
}]);

See how $log is injected, instead of the standard console.warn? While AngularJS will not print $log statements in Karma’s console, avoid side effects in unit tests as much as possible. I once reduced by half the duration of an application’s unit tests by mocking the tracking HTTP requests — which were all silently failing in a local environment, obviously.

describe('factories', function() {

  beforeEach(module('factories'));

  var chimp;
  var $log;

  beforeEach(inject(function(_chimp_, _$log_) {
    chimp = _chimp_;
    $log = _$log_;
    sinon.stub($log, 'warn', function() {});
  }));

  describe('when invoked', function() {

    beforeEach(function() {
      chimp.ook();
    });

    it('should say Ook', function() {
      expect($log.warn.callCount).to.equal(1);
      expect($log.warn.args[0][0]).to.equal('Ook.');
    });
  });
});

The pattern for testing filters, services or other injectables is the same. Controllers can be a bit trickier to test, though, as we will see now.

Controllers

Testing a controller could lead to some confusion. What do we test? Let’s focus on what a controller is supposed to do. You should be used to considering any tested element as a black box by now. Remember that AngularJS is a model-view-whatever (MVW) framework, which is kind of ironic because one of the few ways to define something in an AngularJS application is to use the keyword controller. Still, any kind of decent controller usually acts as a proxy between the model and the view, through objects in one way and callbacks in the other.

The controller usually configures the view using some state objects, such as the following (for a hypothetical text-editing application):

angular.module('textEditor', [])

.controller('EditionCtrl', ['$scope', function($scope) {
  $scope.state = {toolbarVisible: true, documentSaved: true};
  $scope.document = {text: 'Some text'};

  $scope.$watch('document.text', function(value) {
    $scope.state.documentSaved = false;
  }, true);

  $scope.saveDocument = function() {
    $scope.sendHTTP($scope.document.text);
    $scope.state.documentSaved = true;
  };

  $scope.sendHTTP = function(content) {
    // payload creation, HTTP request, etc.
  };
}]);

Chances are that the state will be modified by both the view and the controller. The toolbarVisible attribute will be toggled by, say, a button and a keyboard shortcut. Unit tests are not supposed to test interactions between the view and the rest of the universe; that is what end-to-end tests are for.

The documentSaved value will be mostly handled by the controller, though. Let’s test it.

describe('saving a document', function() {

  var scope;
  var ctrl;

  beforeEach(module('textEditor'));

  beforeEach(inject(function($rootScope, $controller) {
    scope = $rootScope.$new();
    ctrl = $controller('EditionCtrl', {$scope: scope});
  }));

  it('should have an initial documentSaved state', function(){
    expect(scope.state.documentSaved).to.equal(true);
  });

  describe('documentSaved property', function() {
    beforeEach(function() {
      // We don't want extra HTTP requests to be sent
      // and that's not what we're testing here.
      sinon.stub(scope, 'sendHTTP', function() {});

      // A call to $apply() must be performed, otherwise the
      // scope's watchers won't be run through.
      scope.$apply(function () {
        scope.document.text += ' And some more text';
      });
    });

    it('should watch for document.text changes', function() {
      expect(scope.state.documentSaved).to.equal(false);
    });

    describe('when calling the saveDocument function', function() {
      beforeEach(function() {
        scope.saveDocument();
      });

      it('should be set to true again', function() {
        expect(scope.state.documentSaved).to.equal(true);
      });

      afterEach(function() {
        expect(scope.sendHTTP.callCount).to.equal(1);
        expect(scope.sendHTTP.args[0][0]).to.equal(scope.document.text);
      });
    });
  });
});

An interesting side effect of this code chunk is that it not only tests changes on the documentSaved property, but also checks that the sendHTTP method actually gets called and with the proper arguments (we will see later how to test HTTP requests). This is why it’s a separated method published on the controller’s scope. Decoupling and avoiding pseudo-global states (i.e. passing the text to the method, instead of letting it read the text on the scope) always eases the process of writing tests.

Directives

A directive is AngularJS’ way of teaching HTML new tricks and of encapsulating the logic behind those tricks. This encapsulation has several contact points with the outside that are defined in the returned object’s scope attribute. The main difference with unit testing a controller is that directives usually have an isolated scope, but they both act as a black box and, therefore, will be tested in roughly the same manner. The test’s configuration is a bit different, though.

Let’s imagine a directive that displays a div with some string inside of it and a button next to it. It could be implemented as follows:

angular.module('myDirectives', [])
.directive('superButton', function() {
  return {
    scope: {label: '=', callback: '&onClick'},
    replace: true,
    restrict: 'E',
    link: function(scope, element, attrs) {

    },
    template: '<div>' +
      '<div>{{label}}</div>' +
      '<button ng-click="callback()">Click me!</button>' +
      '</div>'
  };
});

We want to test two things here. The first thing to test is that the label gets properly passed to the first div’s content, and the second is that something happens when the button gets clicked. It’s worth saying that the actual rendering of the directive belongs slightly more to end-to-end and functional testing, but we want to include it as much as possible in our unit tests simply for the sake of failing fast. Besides, working with test-driven development is easier with unit tests than with higher-level tests, such as functional, integration and end-to-end tests.

describe('directives', function() {

  beforeEach(module('myDirectives'));

  var element;
  var outerScope;
  var innerScope;

  beforeEach(inject(function($rootScope, $compile) {
    element = angular.element('<super-button label="myLabel" on-click="myCallback()"></super-button>');

    outerScope = $rootScope;
    $compile(element)(outerScope);

    innerScope = element.isolateScope();

    outerScope.$digest();
  }));

  describe('label', function() {
    beforeEach(function() {
      outerScope.$apply(function() {
        outerScope.myLabel = "Hello world.";
      });
    })

    it('should be rendered', function() {
      expect(element[0].children[0].innerHTML).to.equal('Hello world.');
    });
  });

  describe('click callback', function() {
    var mySpy;

    beforeEach(function() {
      mySpy = sinon.spy();
      outerScope.$apply(function() {
        outerScope.myCallback = mySpy;
      });
    });

    describe('when the directive is clicked', function() {
      beforeEach(function() {
        var event = document.createEvent("MouseEvent");
        event.initMouseEvent("click", true, true);
        element[0].children[1].dispatchEvent(event);
      });

      it('should be called', function() {
        expect(mySpy.callCount).to.equal(1);
      });
    });
  });
});

This example has something important. We saw that unit tests make refactoring easy as pie, but we didn’t see how exactly. Here, we are testing that when a click happens on the button, the function passed as the on-click attribute is called. If we take a closer look at the directive’s code, we will see that this function gets locally renamed to callback. It’s published under this name on the directive’s isolated scope. We could write the following test, then:

describe('click callback', function() {
  var mySpy;

  beforeEach(function() {
    mySpy = sinon.spy();
    innerScope.callback = mySpy;
  });

  describe('when the directive is clicked', function() {
    beforeEach(function() {
      var event = document.createEvent("MouseEvent");
      event.initMouseEvent("click", true, true);
      element[0].children[1].dispatchEvent(event);
    });

    it('should be called', function() {
      expect(mySpy.callCount).to.equal(1);
    });
  });
});

And it would work, too. But then we wouldn’t be testing the external aspect of our directive. If we were to forget to add the proper key to the directive’s scope definition, then no test would stop us. Besides, we actually don’t care whether the directive renames the callback or calls it through another method (and if we do, then it will have to be tested elsewhere anyway).

Providers

This is the toughest of our little series. What is a provider exactly? It’s AngularJS’ own way of wiring things together before the application starts. A provider also has a factory facet — in fact, you probably know the $routeProvider and its little brother, the $route factory. Let’s write our own provider and its factory and then test them!

angular.module('myProviders', [])

.provider('coffeeMaker', function() {
  var useFrenchPress = false;
  this.useFrenchPress = function(value) {
    if (value !== undefined) {
      useFrenchPress  = !!value;
    }

    return useFrenchPress;
  };

  this.$get = function () {
    return {
      brew: function() {
        return useFrenchPress ? 'Le café.': 'A coffee.';
      }
    };
  };
});

There’s nothing fancy in this super-useful provider, which defines a flag and its accessor method. We can see the config part and the factory part (which is returned by the $get method). I won’t go over the provider’s whole implementation and use cases, but I encourage you to look at AngularJS’ official documentation about providers21.

To test this provider, we could test the config part on the one hand and the factory part on the other. This wouldn’t be representative of the way a provider is generally used, though. Let’s think about the way that we use providers. First, we do some configuration; then, we use the provider’s factory in some other objects or services. We can see in our coffeeMaker that its behavior depends on the useFrenchPress flag. This is how we will proceed. First, we will set this flag, and then we’ll play with the factory to see whether it behaves accordingly.

describe('coffee maker provider', function() {
  var coffeeProvider = undefined;

  beforeEach(function() {
    // Here we create a fake module just to intercept and store the provider
    // when it's injected, i.e. during the config phase.
    angular.module('dummyModule', function() {})
      .config(['coffeeMakerProvider', function(coffeeMakerProvider) {
        coffeeProvider = coffeeMakerProvider;
      }]);

    module('myProviders', 'dummyModule');

    // This actually triggers the injection into dummyModule
    inject(function(){});
  });

  describe('with french press', function() {
    beforeEach(function() {
      coffeeProvider.useFrenchPress(true);
    });

    it('should remember the value', function() {
      expect(coffeeProvider.useFrenchPress()).to.equal(true);
    });

    it('should make some coffee', inject(function(coffeeMaker) {
      expect(coffeeMaker.brew()).to.equal('Le café.');
    }));
  });

  describe('without french press', function() {
    beforeEach(function() {
      coffeeProvider.useFrenchPress(false);
    });

    it('should remember the value', function() {
      expect(coffeeProvider.useFrenchPress()).to.equal(false);
    });

    it('should make some coffee', inject(function(coffeeMaker) {
      expect(coffeeMaker.brew()).to.equal('A coffee.');
    }));
  });
});

HTTP Requests

HTTP requests are not exactly on the same level as providers or controllers. They are still an essential part of unit testing, though. If you do not have a single HTTP request in your entire app, then you can skip this section, you lucky fellow.

Roughly, HTTP requests act like inputs and outputs at any of your application’s level. In a RESTfully designed system, GET requests give data to the app, and PUT, POST and DELETE methods take some. That is what we want to test, and luckily AngularJS makes that easy.

Let’s take our factory example and add a POST request to it:

angular.module('factories_2', [])
.factory('chimp', ['$http', function($http) {
  return {
    sendMessage: function() {
      $http.post('http://chimps.org/messages', {message: 'Ook.'});
    }
  };
}]);

We obviously do not want to test this on the actual server, nor do we want to monkey-patch the XMLHttpRequest constructor. That is where $httpBackend enters the game.

describe('http', function() {

  beforeEach(module('factories_2'));

  var chimp;
  var $httpBackend;

  beforeEach(inject(function(_chimp_, _$httpBackend_) {
    chimp = _chimp_;
    $httpBackend = _$httpBackend_;
  }));

  describe('when sending a message', function() {
    beforeEach(function() {
      $httpBackend.expectPOST('http://chimps.org/messages', {message: 'Ook.'})
      .respond(200, {message: 'Ook.', id: 0});

      chimp.sendMessage();
      $httpBackend.flush();
    });

    it('should send an HTTP POST request', function() {
      $httpBackend.verifyNoOutstandingExpectation();
      $httpBackend.verifyNoOutstandingRequest();
    });
  });
});

You can see that we’ve defined which calls should be issued to the fake server and how to respond to them before doing anything else. This is useful and enables us to test our app’s response to different requests’ responses (for example, how does the application behave when the login request returns a 404?). This particular example simulates a standard POST response.

The two other lines of the beforeEach block are the function call and a newcomer, $httpBackend.flush(). The fake server does not immediately answer each request; instead, it lets you check any intermediary state that you may have configured. It waits for you to explicitly tell it to respond to any pending request it might have received.

The test itself has two methods calls on the fake server (verifyNoOutstandingExpectation and verifyNoOutstandingRequest). AngularJS’ $httpBackend does not enforce strict equality between what it expects and what it actually receives unless you’ve told it to do so. You can regard these lines as two expectations, one of the number of pending requests and the other of the number of pending expectations.

ngMock Module

The ngMock module22 contains various utilities to help you smooth over JavaScript and AngularJS’ specifics.

$timeout, $log and the Others

Using AngularJS’ injectable dependencies is better than accessing global objects such as console or window. Let’s consider console calls. They are outputs just like HTTP requests and might actually matter if you are implementing an API for which some errors must be logged. To test them, you can either monkey-patch a global object — yikes! — or use AngularJS’ nice injectable.

The $timeout dependency also provides a very convenient flush() method, just like $httpBackend. If we create a factory that provides a way to briefly set a flag to true and then restore it to its original value, then the proper way to test it’s to use $timeout.

angular.module('timeouts', [])

.factory('waiter', ['$timeout', function($timeout) {
  return {
    brieflySetSomethingToTrue: function(target, property) {
      var oldValue = target[property];

      target[property] = true;

      $timeout(function() {
        target[property] = oldValue;
      }, 100);
    }
  };
}]);

And the test will look like this:

describe('timeouts', function() {

  beforeEach(module('timeouts'));

  var waiter;
  var $timeout;

  beforeEach(inject(function(_waiter_, _$timeout_) {
    waiter = _waiter_;
    $timeout = _$timeout_;
  }));

  describe('brieflySetSomethingToTrue method', function() {
    var anyObject;

    beforeEach(function() {
      anyObject = {foo: 42};
      waiter.brieflySetSomethingToTrue(anyObject, 'foo');
    });

    it('should briefly set something to true', function() {
      expect(anyObject.foo).to.equal(true);
      $timeout.flush();
      expect(anyObject.foo).to.equal(42);
    });
  });
});

Notice how we’re checking the intermediary state and then flush()’ing the timeout.

module() and inject()

The module()23 and inject()24 functions help to retrieve modules and dependencies during tests. The former enables you to retrieve a module, while the latter creates an instance of $injector, which will resolve references.

it('should say Ook.', inject(function($log) {
  sinon.stub($log, 'warn', function() {});

  chimp.ook();

  expect($log.warn.callCount).to.equal(1);
  expect($log.warn.args[0][0]).to.equal('Ook.');
}));

In this test case, we’re wrapping our test case function in an inject call. This call will create an $injector instance and resolve any dependencies declared in the test case function’s arguments.

Dependency Injection Made Easy

One last trick is to ask for dependencies using underscores around the name of what we are asking for. The point of this is to assign a local variable that has the same name as the dependencies. Indeed, the $injector used in our tests will remove surrounding underscores if any are found. StackOverflow has a comment25 on this.

Conclusion

Unit testing in AngularJS applications follows a fractal design. It tests units of code. It freezes a unit’s behavior by providing a way to automatically check its response to a given input. Note that unit tests do not replace good coding. AngularJS’ documentation is pretty clear on this point: “Angular is written with testability in mind, but it still requires that you do the right thing.”

Getting started with writing unit tests — and coding in test-driven development — is hard. However, the benefits will soon show up if you’re willing to fully test your application, especially during refactoring operations.

Tests also work well with agile methods. User stories are almost tests; they’re just not actual code (although some approaches, such as “design by contract26,” minimize this difference).

Further Resources

(al, ml)

Footnotes

  1. 1 https://angularjs.org
  2. 2 http://karma-runner.github.io
  3. 3 http://visionmedia.github.io/mocha/
  4. 4 http://chaijs.com
  5. 5 http://sinonjs.org
  6. 6 https://pragprog.com/the-pragmatic-programmer
  7. 7 http://www.smashingmagazine.com/wp-content/uploads/2014/09/01-bricks-opt.png
  8. 8 http://www.smashingmagazine.com/wp-content/uploads/2014/09/01-bricks-opt.png
  9. 9 http://www.smashingmagazine.com/wp-content/uploads/2014/09/02-blackbox-opt.png
  10. 10 http://www.smashingmagazine.com/wp-content/uploads/2014/09/02-blackbox-opt.png
  11. 11 http://karma-runner.github.io
  12. 12 http://www.smashingmagazine.com/wp-content/uploads/2014/09/03-karma-success-opt.png
  13. 13 http://www.smashingmagazine.com/wp-content/uploads/2014/09/03-karma-success-opt.png
  14. 14 https://github.com/lorem--ipsum/smashing-article
  15. 15 http://karma-runner.github.io/0.8/config/configuration-file.html
  16. 16 https://docs.angularjs.org/api/ngMock
  17. 17 http://visionmedia.github.io/mocha/
  18. 18 http://chaijs.com
  19. 19 http://chaijs.com/guide/styles/
  20. 20 http://sinonjs.org
  21. 21 https://docs.angularjs.org/guide/providers
  22. 22 https://docs.angularjs.org/api/ngMock
  23. 23 https://docs.angularjs.org/api/ngMock/function/angular.mock.module
  24. 24 https://docs.angularjs.org/api/ngMock/function/angular.mock.inject
  25. 25 http://stackoverflow.com/a/15318137/863119
  26. 26 http://en.wikipedia.org/wiki/Design_by_contract
  27. 27 https://pragprog.com/the-pragmatic-programmer
  28. 28 https://docs.angularjs.org/guide/unit-testing
  29. 29 https://github.com/lorem--ipsum/smashing-article

The post An Introduction To Unit Testing In AngularJS Applications appeared first on Smashing Magazine.

07 Oct 15:01

Movable Footbridge in Paddington, London Opens and Closes Like a Fan

by Johnny Strategy

Movable Footbridge in Paddington, London Opens and Closes Like a Fan bridges

Movable Footbridge in Paddington, London Opens and Closes Like a Fan bridges

Photographs by Edmund Sumner & Peter Cook, Courtesy Knight Architects

Movable Footbridge in Paddington, London Opens and Closes Like a Fan bridges

Movable Footbridge in Paddington, London Opens and Closes Like a Fan bridges

Movable Footbridge in Paddington, London Opens and Closes Like a Fan bridges

London bridge is not falling down. It’s folding up. Taking their cue from the way a Japanese hand fan folds open, Knight Architects have completed a bridge in London that is both simple and spectacular. In collaboration with structural engineers AKT II, the bridge experts installed 5 steel beams that open and close in sequence, rising to different angles using hydraulic jacks and assisted by counterweights. “Beautiful, efficient bridge design should satisfy both artistic and scientific analysis to be visually legible and structurally truthful,” say the architects. The moving footbridge bridge is located in Paddington, London and spans the 20-meter width of the Grand Union Canal. (via Dezeen)