Pug - retrieving keys from a JSON object - javascript

I'm trying to create a single page website using Pug's templating engine and JSON as a database. Ultimately I'd like to store my different "pages" in the JSON file, and then render that JSON using different variables/mixins in my Pug template, but I keep receiving the errors, cannot read property "company" of undefined.
Any help would be greatly appreciated.
This is my Gulp task to build my Pug files, and pipe the JSON into the template:
// build the Pug files into HTML
gulp.task('build-pug', function buildHTML(){
var dataFile = 'source/javascript/pages.json';
return gulp.src('source/**/*.pug')
.pipe(data(function(file){
return JSON.parse(fs.readFileSync(dataFile));
}))
.pipe(pug({
pretty: true
}))
.pipe(gulp.dest('public'))
.pipe(browserSync.reload({
stream: true
}));
});
This is my pages.json file:
{
"pages": [
{
"year": "2016",
"company": "Abacus",
"home": "./assets/images/2016/home/abacus.png",
"home-url": "http://abacus.com",
"login": "./assets/images/2016/login/abacus.png",
"login-url": "http://abacus.com/login",
"pricing": "./assets/images/2016/pricing/abacus.png",
"pricing-url": "http://abacus.com/pricing"
},
{
"year": "2016",
"company": "Alfred",
"home": "./assets/images/2016/home/alfred.png",
"home-url": "http://alfred.com"
}
]
}
This is in my index.pug file where I'm trying to call keys from my JSON:
section.pricing
h1 Pricing Pages
div.content.pricing
each page in pages
p= page.pages.company

what about replacing your last line in index.pug with
p= page.company

Related

How to note data source in a data JSON file?

I have a few data JSON files similar to this and I want to include a line to note the sources as simple as //source: Cambodia Department of Injustice but JSON files should contain only data.
Should should it be done?
If you can change the data structure slightly, you could add a level for metadata:
{
"metadata": {
"source": "Cambodia Department of Justice",
"source-date": "2015-12-15",
"note": "Ha ha made you look"
},
"countries": {
"USA": { some data }
"Canada": { Some data }
}
}
This is cleaner than use a fake "non-data" country.

Create and Read JSON file

I created a JSON file as follows
{
"fooditems" : [
{
"name": "pizza",
"type": "fastfood",
"price": 10
},
{
"name": "apple",
"type": "fruit",
"price": 1
}
]
}
created a JS file to read the JSON file
const data = require("./data.json");
data1 = JSON.parse(data);
data1.foodData.forEach( foodItem => console.log(foodItem));
When I run the JS, I get error for the json file
Syntax error: Unexpected token o in json at position 1
at JSON.parse
You don't need to parse data since it's already and object. The following should work.
const data = require("./data.json");
data.fooditems.forEach( foodItem => console.log(foodItem));
Note foodData was change to fooditems based on the contents of the data.json file.
Your initial data JSON contains "fooditems", but in the JS file you are trying to process the "foodData". Change the "foodData" to "fooditems" and it should work.
I think that you are trying to access invalid object key in your JS file on the last line.
Instead of
data1.foodData
put
data1.fooditems

Graphql - creating a schema from a generated JSON file

I'm trying to create a custom graphql schema to use on my graphql yoga server. The graphql yoga server is just a proxy to another graphql API from which I have managed to retrieve a schema from in JSON format. Here is a preview of what that schema looks like:
{
"data": {
"__schema": {
"queryType": {
"name": "Query"
},
"mutationType": null,
"subscriptionType": null,
"types": [
{
"kind": "OBJECT",
"name": "Core",
"description": null,
"fields": [
{
"name": "_meta",
"description": null,
"args": [],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "Meta",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "_linkType",
"description": null,
"args": [],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
{
I now want to take this generated JSON schema and use it to create a graphql schema to use in my graphql yoga server. I believe the correct way to do this is by using the new GraphQLSchema method from graphql along with a root query. Here is my code attempting this:
schema = new GraphQLSchema({
query: new GraphQLObjectType({
name: 'Query',
fields: schema.data.__schema
})
});
The above code gives me the following error:
Error: Query.mutationType field config must be an object
Not entirely sure where it's going wrong or if this is the proper approach to creating a graphql schema from generated JSON?
The JSON you have is the results of an introspection query. Unfortunately, introspection will not allow you to copy a remote schema. That's because while it does identify what fields exist in a schema, it does not tell you anything about how they should be executed. For example, based on the snippet you posted, we know the remote server exposes a _meta query that returns a Meta type -- but we don't know what code to run to resolve the value returned by the query.
Technically, it's possible to pass the results of an introspection query to buildClientSchema from the graphql/utilities module. However, the schema will not be executable, as the docs point out:
Given the result of a client running the introspection query, creates and returns a GraphQLSchema instance which can be then used with all GraphQL.js tools, but cannot be used to execute a query, as introspection does not represent the "resolver", "parse" or "serialize" functions or any other server-internal mechanisms.
If you want to create a proxy to another GraphQL endpoint, the easiest way is to use makeRemoteExecutableSchema from graphql-tools.
Here's the example based on the docs:
import { HttpLink } from 'apollo-link-http';
import fetch from 'node-fetch';
const link = new HttpLink({ uri: 'http://your-endpoint-url/graphql', fetch });
async function getRemoteSchema () {
const schema = await introspectSchema(link);
return makeRemoteExecutableSchema({
schema,
link,
});
}
The resulting schema is a GraphQLSchema object that can be used like normal:
import { GraphQLServer } from 'graphql-yoga'
async function startServer () {
const schema = await introspectSchema(link);
const executableSchema = makeRemoteExecutableSchema({
schema,
link,
});
const server = new GraphQLServer({ schema: executableSchema })
server.start()
}
startServer()
graphql-tools also allows you to stitch schemas together if you not only wanted to proxy the existing endpoint, but wanted to add on to it as well.

iterating over JSON object in ejs partial

I am trying to loop over each entry in "default", in my JSON file below, within an EJS partial.
{
"default": {
"1": {
"id": "alertmessages",
"title": "Your Messages",
"subtitle": "Tasks waiting for your attention",
"image": "alert.png",
},
"2": {
"id": "uploadr",
"title": "Upload",
"subtitle": "Upload",
"image": "baskets.png",
},
etc............
}
}
I am reading this JSON file into my node.js, parsing it and making it available for my dashboard view. as below
var jsondata = JSON.parse(require('fs').readFileSync('./app/routes/dashboard/buttons.json', 'utf8'));
var content = {
title: 'Dashboard',
user: req.user,
buttonsdata: jsondata
};
res.render('dashboard', content);
My dashboard view, includes an ejs partial in which I am trying to loop over all the objects contained within default (this number may vary). I want to do this without Jquery. But having trouble getting any of the suggestions working that I have found on other threads.
console.log("<%= buttonsdata.default.[1].id %>")
gives me what I would expect, however if i try and console log buttons.length, which is used in loop examples I have seen, it just comes up blank.
also how can I console log the entire contents of the object to see its structure?
thirdly - this object, in this manner as I can tell is available through ejs, however not to core javascript and i can only access it using the ejs <% %> tags. is this a correct understanding?
You can use Object.keys():
const buttonsdata = {
"default": {
"1": {
"id": "alertmessages",
"title": "Your Messages",
"subtitle": "Tasks waiting for your attention",
"image": "alert.png",
},
"2": {
"id": "uploadr",
"title": "Upload",
"subtitle": "Upload",
"image": "baskets.png",
}
}
};
Object.keys(buttonsdata.default).forEach(function (key) {
console.log(buttonsdata.default[key].id);
});
Now, according to your code, in the view should work like this:
<ul>
<% Object.keys(buttonsdata.default).forEach(function(key) { %>
<li><%= buttonsdata.default[key].id %></li>
<% }) %>
</ul>
Your json contains only objects, it doesn't have any arrays in it, so you won't be able to use buttonsdata.length
Displaying the whole object - display the object from within your controller, not your template. Look at this answer to see how
this object is available through ejs - yes, that's a correct understanding - I assume that by core javascript you mean the javascript that's executed in the browser. The whole ejs template is processed on the backend.

Parsing JSON file with AngualrJS

I'm learning AngularJS and running some tests, but I'm having the following problem: I'm trying to read a JSON file, parse it into an object and show its properties on the screen. I read that $http parse the JSON text automatically, so I wrote the following code:
$http.get("/people").success(
function(data, status, headers, config) {
$scope.data = data.people;
}
);
This is my JSON file:
{ "people": [
{
"id": "0",
"name": "Cave Jhonson",
"company": "Aperture Science"
},
{
"id": "1",
"name": "Gustavo Fring",
"company": "Los Pollos Hermanos"
}
]
}
Which is in my project folder. I'm running a Python server. Finally, I'm trying to show the information with a simple HTML:
<p>{{data.people[0].name}}</p>
But when I open the page in Firefox the information doesn't show up and I get this error message: " Error: JSON.parse: expected property name or '}' "
My JSON is valid, so I can't understand why $http is not parsing it.
this line is inccorrect: <p>{{data.people[0].name}}</p>
You already put the code on scope in data so use that
<p>{{data[0].name}}</p>
Or you can use ng-repeat to show all the records like this
<div ng-repeat='item in data'>
<p>Id: {{item.id}}, Name: {{item.name}}, company: {{item.company}}</p>
<div>

Categories