Use Destructuring Assignment to Assign Variables from Objects review

Tell us what’s happening:
A little help with my code in this challenge. Thanks very much

Your code so far


function getLength(str) {
  "use strict";

  // change code below this line
  const length = str.length; // change this
  // change code above this line

  return {length} = len; // you must assign length to len in line

}

console.log(getLength('FreeCodeCamp'));

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/es6/use-destructuring-assignment-to-assign-variables-from-objects/

Hah, I saw a few people were having problems with this challenge. It is incredibly confusing

So you want to just return len at the end, you don’t return things in like that, destructuring doesn’t change how JS works.

Strings are converted to objects to do useful things to them in JS, and they have a property length (among other things). So you can use destructuring to grab things from that object. So here, I’m saying I want the properties length, valueOf and constructor from the string “foo” (which is the value of test)

const test = "foo";
const { length, valueOf, constructor } = test;

Which is the same as:

const test = "foo";
const length = test.length;
const valueOf = test.valueOf;
const constructor = test.constructor;
> length
3
> valueOf() # valueOf is a function, not just a value
'foo' # it won't actually return this in practise, it'll blow up because the String object has already been garbage collected so the reference no longer exists
> constructor
[Function: String]

With the destructuring, you’re grabbing the properties by their name. You can also assign them to another name (maybe you’re using those values a lot and the word constructor is too long, you just want c instead or something):

const test = "foo";
const { length: l, valueOf: v, constructor: c } = test;

So you get

> l
3
> v()
'foo' # again, in practice this won't work
> c
[Function: String]

This is an ultra-confusing challenge because it assumes a knowledge of how JS works that you’re not likely to have, b. uses something as an example that I honestly can’t see any real-world use for, and c. forces you to use something (assigning inside destructuring) that is not used very much. It’s a really bad example to use: destructuring is very, very useful, but this is not a good display of that usefulness in any way at all really.

9 Likes

length is an inbuilt Js property of str that can be assigned to len
so all you need to do is
property length of str is assigned to local variable len

1 Like

Dan,

Thank you for this explanation. I was tearing my hair out looking at that lesson. What is the most common usage for destructuring in everyday life? It seems like its sort of a quality of life feature that allows assigning object properties to variables much quicker. Is there more to it than that? Thanks.

JPM

Yes, it is kinda a quality of life thing. Basically, you can assign things to objects using shorthand like

const myObj = { foo: 1, bar: 2 }

Instead of

const myObj = {}
myObj.foo = 1
myObj.foo = 2

There wasn’t the same thing for extracting things, but destructuring now provides that:

const { foo, bar } = myObj

rather than

myObj.foo
myObj.bar

It is, like a lot of the small ES6 syntax adjustments, a way to be more specific about what exactly is happening at a particular stage of your program. You describe the exact shape of the data you want up front, and if something errors, it generally errors earlier than it would otherwise (which is what you want), and error messages tend to be more specific (again, what you want).

You don’t really see the benefit from small toy examples unless you’ve programmed in JS for a while, but I guess the most obvious example is pulling value from API responses. This is a basic GitHub API response:

{
  "login": "DanCouper",
  "id": 573694,
  "node_id": "MDQ6VXNlcjU3MzY5NA==",
  "avatar_url": "https://avatars3.githubusercontent.com/u/573694?v=4",
  "gravatar_id": "",
  "url": "https://api.github.com/users/DanCouper",
  "html_url": "https://github.com/DanCouper",
  "followers_url": "https://api.github.com/users/DanCouper/followers",
  "following_url": "https://api.github.com/users/DanCouper/following{/other_user}",
  "gists_url": "https://api.github.com/users/DanCouper/gists{/gist_id}",
  "starred_url": "https://api.github.com/users/DanCouper/starred{/owner}{/repo}",
  "subscriptions_url": "https://api.github.com/users/DanCouper/subscriptions",
  "organizations_url": "https://api.github.com/users/DanCouper/orgs",
  "repos_url": "https://api.github.com/users/DanCouper/repos",
  "events_url": "https://api.github.com/users/DanCouper/events{/privacy}",
  "received_events_url": "https://api.github.com/users/DanCouper/received_events",
  "type": "User",
  "site_admin": false,
  "name": "Dan Couper",
  "company": "@SoPost  ",
  "blog": "",
  "location": "Newcastle, UK",
  "email": null,
  "hireable": true,
  "bio": null,
  "public_repos": 33,
  "public_gists": 69,
  "followers": 32,
  "following": 93,
  "created_at": "2011-01-20T00:46:50Z",
  "updated_at": "2018-06-08T23:46:39Z"
}

And with destructuring, I could do something like:

async function grabUserInfo(username) {
  const request = await fetch(`https://api.github.com/${username}`)
  const response = await request.json();
  const userInfo = printUserInfo(response);
  console.log(user info);
}

function printUserInfo({ type, name, location = 'not provided'}) {
  return `${name} is a GitHub ${type}. Location: ${location}`;
}

So hitting the API with my GH username will log DanCouper is a GitHub User. Location: Newcastle, UK.

The key thing is I can destructure directly as a function parameter, so the printUserInfo function takes the response object, grabs the field values I want, and prints them out. If I pass it an object of the wrong ‘shape’, it will blow up straightaway. It also demonstrates that I can pass defaults: I don’t have to provide a location to GitHub, so that field might not be there (I think the API might just return an empty string if it’s left blank though, so example may not be totally correct, but hopefully you can see the reasoning)

And more in-depth:

http://exploringjs.com/es6/ch_destructuring.html

5 Likes

Thanks Dan!

It is always nice getting some real world examples of what I’ve learned here. I should have known to go check out CSS-Tricks. Great resource.

JPM

1 Like

Thank you so much for this lucid explanation! I was so frustrated till I saw this!
:pray:t5:

1 Like

Thanks for the explanation and helping me through this exercise.

1 Like

Thank you so much for this explanation! Very clear - perhaps there’s a way to put your explanation into the challenge or the hints for this topic.

2 Likes

This was absolutely helpful, honestly it was confusing to me with the challenge, I did it but I didn’t quite understand what I did since I was just looking at the example as a guide to write my own code. But thanks to your post now I do.

1 Like