How do you write a JSON file?

How do you write a JSON file?
0

#1

I’m trying to do the random quote generator, but we didn’t learn how to create a JSON file. I created an array holding 20 sub-arrays, each with a quote and its author, but I think it’s supposed to be an object.(?) Can someone just post a small example of a JSON file of strings, something that the code would work with.

$.getJSON("quotes.json", function(json) {
       $(".quotebox").html(JSON.stringify(json));
});

json.forEach(function(value){
          var keys = Object.keys(value);
		  html += "<div class="quote");
		  keys.forEach(function(key) {
		      html += "<strong>" + key + "</strong>": + value[key] + "<br />";
});
html += "</div> <br />"; });

  //Generates a random number, 0 - 255.
  $("#newQuote").click(function() {
  var myQuote = Math.floor(Math.random() * 20);

// User can click to get a new quote.
$("#newQuote").on("click", function() {
              $(".quote").html("Your quote: ");
                    }

#2

You can’t access files the way you’re expecting here. Passing a filename into getJSON will send a request to whichever server is hosting your script. If you haven’t configured a server to host that file, you’re going to get an error.

For a front-end project, you don’t need (or want) to have the quotes contained in a separate file. It’s best to hardcode your quotes in your app or use some existing API. I think you are already on the right track with an array of quotes.


#3

Like @PortableStick said, you are on your way. Just declare the json variable as an an array of strings (quotes) to use with your forEach function. You do have a couple of lines with syntax errors to fix also (see below).

html += "<div class="quote");

and

html += "<strong>" + key + "</strong>": + value[key] + "<br />";

#4

I thought we were supposed to use JSON for this. I would much rather just use an array. Thanks for pointing out the errors. I basically pasted in that code from the cat app and just changed the class/id names. I’ll take a look at the rest of it.

However, for future reference, how would you write a JSON file for a series of quotes and their authors?


#5

To literally write by hand:

http://www.json.org/

That’s the rules for JSON, all of them - the diagrams show you how to structure a correct file. If you take the diagrams out, the specification for JSON is about 150 words. It just describes how to write a text file that you give the file extension of .json to, what you’re allowed to use for it. Relevant bit:

An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).
A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.

Normally you generate the JSON from a database or similar in whatever language is used backend, rather than ever writing anything by hand


#6

I solved that challenge using an external file of quotes formatted as JSON.

Here's the link:

https://alper6.github.io/Fcc/quotes/


#7

@LisaWillCode - You can see the external file @alper6 is using in his project at https://alper6.github.io/Fcc/quotes/quotes.txt


#8

I think people are getting a bit confused here. There is no requirement for JSON in the challenge. What you need is a bunch of quotes. There are different ways to do this:

  1. One way is to hard code them into an array in your JS. Something like:
var quoteArr = [
  "quote 1",
  "quote 2",
  "quote 3"
];

If you wanted, you could have each element in the array be an abject if you wanted to encode the author separately.

  1. Another way would be to make an API call with something like $.getJSON that will return a JSON or JS object. There are APIs like forismatic or mashape.

  2. The OP seems to be asking about writing a JSON file with his own quotes. This is an option and essentially the same as hardcoding the quotes into an array in the JS, just that now there is an extra step of having to load your JSON file. Of course there is also the problem of having to find somewhere to host that JSON file (you can’t do that in codepen.)

I think one of the first two options is the best, the first one being the easiest. There is no mention of JSON in the challenge - that is just one possible solution to the question, “Where am I going to get these quotes?”


#9

If you have an object or an array in your code which you want to put in JSON format, then just use JSON.stringify(array). But this is usually done to send data over HTTP. If you just have the quotes locally, there is no need.

If you want to generate a JSON file from some code, you can use Node:

const fs = require(‘fs’);
const path = require(‘path’);

const array = [‘one’, ‘two’, ‘three’];

fs.writeFileSync(path.join(__dirname, ‘file.json’), JSON.stringify(array));


#11

@ksjazzguitar, I know the requirements didn’t say we had to use JSON, but because the project comes right after teaching a bit of JSON with the cat photos using it, it seemed like that was the expectation, that we would apply what we’d learned. I did write this as an array containing other arrays.

Why would I want to construct objects inside of the containing array? For example, if I have:

[
["A black cat crossing your path signifies that the animal is going somewhere.", "Groucho Marx"],
["What we think, we become.", "Buddha"]
];

it seems that would be easier to use than this:

[
{"quote": "A black cat crossing your path signifies that the animal is going somewhere.", "author": "Groucho Marx"},
{"quote": "What we think, we become.", "author": "Buddha"}
];

@alper6, thanks for sharing your file, and @RandellDawson, thanks for the link to the actual file. One thing I notice about it is that it has a .txt extension rather than a .json extension. I assume the format (objects within a containing array) would be the same.

@DanCouper, I am overwhelmed by all the rules at once. I appreciate the link, will save it for when I’m actually going to use JSON. (I would so love to just get comfortable with CSS & JS first.)


#12

The extension does not matter in this case, the browser won’t try to handle that file based on its extension, only the content matters. The server will send whatever filepath you specify in Ajax call.
Since GitHub Pages provides free space accepting GET requests, this looked like a simpler solution for me than dealing with API keys and web services. YMMV.

All my FCC related work is open for everyone, if anyone's interested:

https://github.com/alper6/Fcc


#13

Yes, you could do it that way. Which is better? It’s somewhat subjective. I would argue that the array of objects is slightly better because it’s clearer. For example, I think that quoteArr[randNum].quote is clearer than quoteArr[randNum][0] - when I look at the first, it is very clear what it is. If another programmer has to look at that code a year from now, which would be clearer? I think objects with meaningful names are better. Arrays are good for data that is a list of like elements, that are meant to be indexed through. But both options work.

I know the requirements didn’t say we had to use JSON, but because the project comes right after teaching a bit of JSON with the cat photos using it, it seemed like that was the expectation,

Perhaps. But I think it is just that that is the group of projects after the JavaScript section. If they wanted you to use JavaScript, they would have said it. And you will definitely have to use API calls to get JSON objects on the other challenges.

But if you want, you can call a quote API get get served a JSON object.


#14

Ok, so an array is an ordered list of things (ideally the same kind of things, like all strings or all numbers). You can access the things by the index they’re at. But that is not not easy to do because you need to know, in advance, where the thing is in the array. An object is a group of things (of any kind) in no particular order, but each of those things has a name you can use to access them.

So like a dictionary vs. a list of all the words in the dictionary. If you want associate a word with its definition, let a user look it up, use the former. If you want to know how many words there are, or get all words starting with “z” or whatever, use the latter. Like:

{
  "cow": "animal that moos",
  "cat": "animal that meows",
  "dog": "animal that barks",
  "sheep": "animal that baas"
}

vs

["cow", "cat", "dog", "sheep"]

This

[
["A black cat crossing your path signifies that the animal is going somewhere.", "Groucho Marx"],
["What we think, we become.", "Buddha"]
];

is much harder to use than

[
{"quote": "A black cat crossing your path signifies that the animal is going somewhere.", "author": "Groucho Marx"},
{"quote": "What we think, we become.", "author": "Buddha"}
];

Because in the first, there is no information associated with each item; each item id just a list of strings. In the second one, each item has a name that can be used to look up its corresponding value. The first is the wrong structure, as it is needlessly hard to use, second is the correct structure. A list is an ordered collection of similar things: in your case the text of the quote and the author of the quote are not similar things (they’re both strings, but that’s where the similarity ends)


#15

Thanks for your explanation, @DanCouper. It makes perfect sense, for larger arrays or for when I am trying to access a specific item, so you’ve convinced me of the value of using objects in those cases.

In this case, though, the code accesses each item in the container array randomly, so the index number makes sense for random number generation. Each sub-array has only two items, the quote and the author, and it’s obvious which is which. For this purpose, I’d argue that the array is more efficient.


#16

Obvious how? While you can make the claim that the array of arrays is plenty obvious for a small little program like this where you can see the data structure and the output code on the same screen, imagine if this program blossomed into a large complex system of files where your array of arrays was declared in a different file. Would it be obvious then too? What if some other programmer came in and decided to put a date element into each array as the first element of each subarray. They’d have to go in and recode all the subarray indexes.

I’d be careful with the word “obvious”. For me, I don’t measure it by how obvious to me, right now, with this simple version of the program, that I just wrote. I want it to be clear to someone else that is looking at the code for the first time, a year from now, after this has been reved a few times and has grown.

Develop good habits now. Like I tell my music students - The way you practice is the way you perform.

Efficient how? A few fewer key strokes? I don’t think you can argue that it’s faster to run. Maybe it’s marginally faster (I don’t know), not in any way that would be meaningful - the retrieval for either is still O(1).

Efficiency can be a good thing to worry about. But we have to be careful not to worship it at the expense of clarity. If I have to make a few extra keystrokes to make something more readable and maintainable, then I’m all for it. It may not matter on something small like the Quote Generator, but in a 10k like program worked on by a team of 6 in different countries - it will make a huge difference. I would suggest developing that way of thinking now.


#17

I recently heard a tennis coach tell a kid:

“Train like you’re competing and compete like you’re training.”

I think I need to apply that to my coding, too. I skip error handling and testing all the time until my code is ‘done’, then I clean it up with the stuff that should have been in there all along :slight_smile:


#18

@ksjazzguitar, by more efficient, I meant more efficient for me to code. Remember, I’m very much a beginner, so my goal is just to get it to work. At this point, I can’t even consider performance speed. (Not to mention that we haven’t yet been taught that.)

This isn’t going to be worked on by another developer in a year. I do understand your point, but again, right now it’s all I can manage to get it to work.


#19

Interesting. I think the point is that if you develop good enough habits, then you don’t have to worry about them when the ess hits the fan. Similarly I tell my jazz students (for whom scale practice is a major component) “The reason we practice scales so much is so that we can forget about them.” If you’re thinking about scales, then you aren’t thinking about music. Similarly, if we develop good, instinctual coding habits, they will flow automatically when we’re stressed.


#20

I get that. I’ve been there. But I also remember having to go back and break some bad habits that I formed by doing things that seemed easier at the time. The road to bad code is paved with “I don’t care, just make it work.” Part of what you are trying to learn is how to code.

But again, when I look back on my first projects, I have to laugh. You can take or leave our advice however you want. But I think you’ll find yourself doubling back to our way of thinking eventually. Good luck.


#21

Bad code eventually gets you wanting to write good code.

There’s a CodeNewbie Podcast interview with Paul Ford in which he talks about the importance of beginners learning the right concepts when they feel the need for them.

His example was about the right time to start learning the DRY principle (i.e. Don’t Repeat Yourself).

He suggested that while DRY code is better, a beginner won’t really learn the lesson until they have grown sick and tired of maintaining non-DRY code they wrote.

@LisaWillCode, the same is true of your array vs. objects choice. Right now, the way you’re using arrays works for you, so keep at it! Arrays were a big stumbling block for me in the early days, so being able to wrap your head around 2D arrays and manipulate the data from them is a real win. One day, maybe soon, as @ksjazzguitar suggests, you’ll want to be able to access data via a nice name rather than by an index in an array, or an array embedded within another array, and at that point objects will be there for you .