How to get specific data from large json object into Jade mixin - javascript

This is the json from my sever:
data = {"id":393, "state":"mississippi", "lat":null, "lng":null, "title":"someTitle", "country":null};
I then pass that through a Jade temple like so: res.render('editUpload', {fromServer:data});
Then in my Jade template I have this:
var data = !{fromServer};
console.log(data.address);
Which correctly prints mississippi
However, I'm trying to get my mixins to use that data
Mixin:
mixin textBoxMixin(name, label, value)
div(style="display:flex; width:100%;")
span.label #{label}
input(type="text", name="#{name}", value="#{value}")
Then I use that like this:
+textBoxMixin("title", "Title", fromServer)
which fills in the text box with the entire json "{"id":393, "state":"mississippi", "lat":null, "lng":null, "title":"someTitle", "country":null}" so I go and try this:
+textBoxMixin("title", "Title", fromServer.title)
it prints "undefined".
How do I get this mixin to accept what should just be fromServer.title?
I've tried JSON.stringify(fromServer), data.address (which obviously doesn't work because data is undefined during the rendering of the page). I know that I could go back to my server and parse out all the json there and pass each item as an individual item, but that would be a giant pain since my json is actually much larger than what I've posted here.
The problem was that I was sending the json from the route.js file to the template after having passed it through JSON.stringify(), this let me use var data = !{fromServer}; in the page's scripts, but Jade couldn't parse the String. So now I'm doing this in the route so that I have both the json available for templating and the String for JavaScript:
data = rows[0][0];
stringFromServer = JSON.stringify(rows[0][0]);
res.render('editUpload', {fromServer:data, stringFromServer:stringFromServer, username: req.session.user});

When you reference parameters in your mixin definition, you pass them exactly as if it were normal pug code, without quotes and braces.
mixin textBoxMixin(name, label, value)
div(style="display:flex; width:100%;")
span.label= label
input(type="text", name=name, value=value)
+textBoxMixin("title", "Title", fromServer.title)
Here's what renders:
Also, Jade is now Pug, and I know you know that since you tagged Pug in this question, you should start referencing it as Pug :).

Related

Get options sent to pug with space in the name

I am trying to send JSON options into a pug file with a space in the attribute names.
For example, inside an express get request:
let json = {"Attribute Name With Spaces": "Value"}
res.render('loader.pug', json);
How do I access this data in the pug file? It is difficult to change the format of the json because it is external and not something I made myself.
Pug makes locals available under the locals property so you can simply use the following...
h1= locals["Attribute Name With Spaces"]
p Here's the var #{locals["Attribute Name With Spaces"]}
I couldn't find any official documentation for this so it might not always be a reliable option.
Another option to make this easier would be to simply bundle all your json properties under a single object...
res.render("loader.pug", { props: json });
Then you can use something like this
h1= props["Attribute Name With Spaces"]
p #{props["Attribute Name With Spaces"]}
Alternately, transform your object to normalise the keys
res.render(
"loader.pug",
Object.fromEntries(
Object.entries(json).map(([key, val]) => [key.replaceAll(" ", "_"), val])
)
);
and use
h1= Attribute_Name_With_Spaces

How to append an item to a JSON stored in a file?

Im triying to write a JSON object to a DB with FS but it´s not working as expected. What i want to do is write the JSON data inside this: [] Example:
[
{"name":"jhon"},
{"name":"jhonathan"}
]
Here is the code:
Thanks.
The comment you provided doesn't make much sense, because the JSON data you provided in the post and in the comments is completely different. But I get the gist of it. I guess you have a JSON file containing an array and you want to push new items to it. Let's do this.
The thing is, when you call fs.appendFile, you're only writing to the end of the file. You're not following JSON format by doing so.
You need to do this:
Read file content.
Parse JSON text into an object.
Update the object in memory.
Write object in JSON format back to the file system.
I'll call the synchronous methods for simplicity's sake, but you should be able to convert it to async quite easily.
const path = __dirname + 'db.json'
// Reading items from the file system
const jsonData = fs.readFileSync(path)
const items = JSON.parse(jsonData)
// Add new item to the item list
items.push(newItem)
// Writing back to the file system
const newJsonString = JSON.stringify(items)
fs.writeFileSync(path, newJsonString)

How to access a json object in javascript files from a model passed to the view

I have a JSON object in my database that contains html inside it. I pass the object as part of a model to my view. I need to access the object and read it in the javascript files for the page. However when i try and assign the object to a global variable in my html file i cannot access it in my javascript file.
I tried reading the object as a string it returns decoded html (
"page-1":) which i cant do anything with. If i call #Html.Raw(#Model.CourseContent.ExpectedResult) it created the JSON object as expected. However in my javascript file it is listed as undefined. I have no idea how to solve this.
#model DataTransferObjects.Models.UserCourseAndContent
<script>
var totalPages = '#Model.CourseContent.TotalPages';
var expectedResults = #HTML.Raw(#Model.CourseContent.ExpectedResult)
</script>
The json object that comes out when i use the above code looks like
var expectedResults = {
"page-1": "<head></head><body></body>",
"page-3": "<head></head><body><h1>My Cool News Article</h1><p>Welcome
to my news article, you’ll find some cool news here.</p>
<Our most recent
news</<p>Below you’ll find my most recent news!</p></body>"
};
I expected it to be an actual json string but instead ive got an object (?) i am confused as to how to decode the html out of it then turn the resulting json obejct into a json string to be read in the javascript file.
Any help would be great!
var expectedResults = {
"page-1": "<head></head><body></body>",
"page-3": "<head></head><body><h1>My Cool News Article</h1><p>Welcome
to my news article, you’ll find some cool news here.</p>
<Our most recent
news</<p>Below you’ll find my most recent news!</p></body>"
};
// Parse JSON
const parsedJSON = JSON.parse(JSON.stringify(expectedResults));
// Access to properties
const page-1 = parsedJSON['page-1'];
const page-3 = parsedJSON['page-3'];

Access sessionStorage in template EmberJS

I have saved some data in sessionStorage (a large JSON response from ajax) in EmberJS, and wanted to know if there was a way to access that directly in template handlebars. If not, what would be my alternatives? I have tried {{sessionStorage.getItem("data"}} in template but it gives me an error saying "Expecting 'ID', got 'INVALID'".
You should set the item in sessionStorage to a variable in your component.js like this:
init:function(){
this.set('sessionStorageData', sessionStorage.getItem('data'));
}
and use it in your hbs like this:
{{sessionStorageData}}

Using handlebars.js for dynamic user content?

Handlebars is commonly used on static predefined html templates and then given dynamic data via JSON, but what if the template itself comes from json?
I'm trying to build a community forum whereby I have a template that gets filled in for where the users post goes. The post itself however also contains template information (which is dynamic). How can I get handlebars to process a dynamic template that just came out of ajax?
For example, a users post can contain any or all of the following in any order: text, pictures, links, videos, etc.
The content will look something like this:
{{text-open}} blablabla heres a picture {{text-close}}{{image-open}}
http://someRandomUrl.com {{image-close}} {{image-open}}
http://anotherRandomUrl {{image-close}}
I'm not sure how to do this with handlebars. I have the feeling maybe I should just use a string replace function? But would that be the optimal method?
You just have to compile the template:
fetch("post.hbs")
.then(source => Handlebars.compile(source))
.then(postTemplate => {
// Do stuff, then fill the template:
postElement.innerHTML = postTemplate(postData);
});

Categories

Resources