Load JSON from file vs. as variable for timeline events - javascript

I use the SMILES timeline loading event data as JSON from file and as variable.
Loading from file works fine using the samplecode from the homepage:
tl = Timeline.create(document.getElementById("div-timeline"), bandInfos);
Timeline.loadJSON("js/timelinedata.json", function(json, url) {
eventSource.loadJSON(json, url); });
Here is the content of my file timelinedata.json:
{"dateTimeFormat": "iso8601",
"events" : [
{"start": "1924",
"title": "Barfusserkirche",
"description": "by Lyonel Feininger, American/German Painter, 1871-1956",
"image": "link to an image",
"link": "link to an article"
}
]}
However when i paste the JSON into a var and try to load it i get complains.
This is how i populate my var:
function TimeTestData1(){
var TimelineEvent = {"dateTimeFormat": "iso8601",
"events" : [
{"start": "1924",
"title": "Barfusserkirche",
"description": "by Lyonel Feininger, American/German Painter, 1871-1956",
"image": "link to an image",
"link": "link to an article"
}
]};
return TimelineEvent;
}
And use it in timeline:
var tdata = TimeTestData1();
console.dir(tdata); // this looks fine
// [ timeline code ]
Timeline.loadJSON(tdata, function(json, url) { eventSource.loadJSON(json, url); });
I get an "alert" popup with the message:
Failed to load json data from [object Object] Not Found
When i use JSON.stringify(tdata) like this:
Timeline.loadJSON(JSON.stringify(tdata), function(json, url) {
eventSource.loadJSON(json, url); });
The browser tells me (using alert popup):
Failed to load json data from {"dateTimeFormat":"iso8601","events":[{"start":1924,"title":"Barfusserkirche","description":"by Lyonel Feininger, American/German Painter, 1871-1956","image":"link to an image","link":"link to an article"}]}
Not Found
here is the complete code of the timeline function:
function LoadTimeline() {
var tl;
var eventSource = new Timeline.DefaultEventSource(0);
//var tdata = TimeTestData1();
var theme = Timeline.ClassicTheme.create();
theme.timeline_start = new Date(Date.UTC(1890, 0, 1));
theme.timeline_stop = new Date(Date.UTC(2020, 0, 1));
var d = Timeline.DateTime.parseGregorianDateTime("1950") // set date to display
var bandInfos = [
Timeline.createBandInfo({
width: "70%",
intervalUnit: Timeline.DateTime.YEAR,
intervalPixels: 100,
eventSource: eventSource,
date: d
}),
Timeline.createBandInfo({
width: "30%",
intervalUnit: Timeline.DateTime.CENTURY,
eventSource: eventSource,
date: d,
intervalPixels: 200
})
];
bandInfos[1].syncWith = 0;
bandInfos[1].highlight = true;
tl = Timeline.create(document.getElementById("div-timeline"), bandInfos);
Timeline.loadJSON("js/timelinedata.json", function(json, url) {
eventSource.loadJSON(json, url); });
} //JSON.stringify(tdata) or tdata or "js/timelinedata.json"
How do I have to pass my event json var so timeline eats it?

Timeline.loadJSON expects a URL, not JSON. Try removing that call altogether and only call eventSource.loadJSON(tdata, url); instead. (not sure what the url-parameter is for in this case, documentation looks really bad for this project)

Not sure if anyone will see this but loadJSON() is expecting a JSON object as the first parameter, and not a string (which is what you are doing by saying JSON.stringify()). So as long as tdata is a JSON object compatible with Timeline, then all you need to do is
eventSource.loadJSON(tdata, window.location.href)

Related

What is wrong with my JSON output for a Slack Message payload?

I have set up what I think should be a working JSON output to send a message in slack but Slack keeps rejecting it.
I have tried multiple different message layout formats using the guides on slack's api site, but so far the only method that has successfully sent is a fully flat JSON with no block formatting.
function submitValuesToSlack(e) {
var name = e.values[1];
var caseNumber = e.values[2];
var problemDescription = e.values[3];
var question = e.values[4];
var completedChecklist = e.values[5];
var payload = [{
"channel": postChannel,
"username": postUser,
"icon_emoji": postIcon,
"link_names": 1,
"blocks": [
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Name:*\n " + name
}
]
}]
}];
console.log(JSON.stringify(payload, null, "\t"));
var options = {
'method': 'post',
'payload': JSON.stringify(payload)
};
console.log(options)
var response = UrlFetchApp.fetch(slackIncomingWebhookUrl, options);
}
When I run this, I get the following output:
[
{
"channel":"#tech-support",
"username":"Form Response",
"icon_emoji":":mailbox_with_mail:",
"link_names":1,
"blocks":[
{
"type":"section",
"fields":[
{
"type":"mrkdwn",
"text":"*Name:*\n test"
}
]
}
]
}
]
Which I believe is correct, however slack api just rejects it with an HTTP 400 error "no text"
am I misunderstanding something about block formatting?
EDIT:
To Clarify, formatting works if I use this for my JSON instead of the more complex format:
{
"channel":"#tech-support",
"username":"Form Response",
"icon_emoji":":mailbox_with_mail:",
"link_names":1,
"text":"*Name:*\n test"
}
The reason you are getting the error no_text is because you do not have a valid message text property in your payload. You either need to have a text property as top line parameter (classic style - your example at the bottom) or a text block within a section block.
If you want to put to use blocks only (as you are asking) the section block is called text, not fields. fields is another type of section bock that has a different meaning.
So the correct syntax is:
[
{
"channel":"#tech-support",
"username":"Form Response",
"icon_emoji":":mailbox_with_mail:",
"link_names":1,
"blocks":[
{
"type":"section",
"text":[
{
"type":"mrkdwn",
"text":"*Name:*\n test"
}
]
}
]
}
]
Also see here for the official documentation on it.
Blocks are very powerful, but can be complicated at times. I would recommend to use the message builder to try out your messages and check out the examples in the docu.

SAPUI5: Routing with parameters - How get correct path of binding context

I am trying to implement routing with parameters as in this walkthrough: https://sapui5.hana.ondemand.com/1.58.7/#/topic/2366345a94f64ec1a80f9d9ce50a59ef
However, instead of getting data as a path
/Invoices(CustomerName='Alfreds%20Futterkiste',Discount=0f,OrderID=10835....
when they do:
oRouter.navTo("detail", {invoicePath:
oItem.getBindingContext("invoice").getPath().substr(1)});
when I use the function in my controller (see onFwdDetail below), I only get a string path:
nodes/0
And this cannot be used in routing (see manifest.json below):
Invalid value "nodes/0" for segment "{detailPath}".
I am assuming it is because my JSON file is structured differently than in the walkthrough. How do I get the correct path with data for routing?
The relevant section of my implementation are as follows:
Data.JSON
{
"nodes": [
{
"text": "Text1",
"status1": "Status10",
"status2". "Status11"
},
{
"text": "Text2",
"status1": "Status20",
"status2". "Status21"
},...]
}
Overview.view.xml
<Table
items="{path: 'mydata>/nodes'}">
...
<ColumnListItem type="Navigation" press="onFwdDetail">
Overview.controller.js
onInit : function() {
var oModel = new JSONModel("model/Data.JSON");
this.getView().setModel(oModel, "mydata");
},
onFwdDetail : function(oEvent) {
var oItem = oEvent.getSource();
var oRouter = sap.ui.core.UIComponent.getRouterFor(this);
oRouter.navTo("detail", {detailPath:
oItem.getBindingContext("mydata").getPath().substr(1)});
console.log(oItem.getBindingContext("mydata").getPath().substr(1));
}
manifest.json
{
"pattern": "details/{detailPath}",
"name": "details",
"target": "details"
}
Their path is a path to an entity of an OData model. Your path is a path to an entity of a JSON model.
Those paths are built entirely different. Most importantly your path contains a slash, while theirs does not. This confuses the parser which tries to match details/{detailPath} and details/nodes/0.
The 0 itself is a valid path in your example. nodes is an array and it's possible to do nodes[0]. It's just that the routing class doesn't like the format.
So what you can do is simply passing the 0 to your detailPath. In your detail view you can then build the original key ("nodes/" + detailPath) and bind your view to that key.
I would also recommend this approach for OData btw:
extract actual keys from bound object
pass keys to your router
in your detail view build a key from the passed arguments
Pseudo code for an OData model:
Controller A:
// read relevant values from binding context
var oContext = oItem.getBindingContext("myModel");
var sKeyName = oContext.getObject("CustomerName");
var sKeyId = oContext.getObject("OrderID");
// trigger navigation
oRouter.navTo("orderDetail", { name: sKeyName, id: sKeyId });
Controller B:
_onRouteMatched: function (oEvent) {
var oModel = this.getModel("myModel");
var that = this;
// read params from routing
var sKeyName = oEvent.getParameter("arguments").name;
var sKeyId = oEvent.getParameter("arguments").id;
// as soon as the metadata of the model are available there is a great API to build keys
oModel.metadataLoaded().then(function () {
var sPath = oModel.createKey("/Invoices", {
CustomerName: sKeyName,
OrderID: sKeyId
});
// sPath should be something like "/Invoices(CustomerName='Troll',OrderID=12345)"
that.getView().bindElement({ path: sPath });
});
},
manifest.json
"pattern": "order/{name},{id}",
"name": "orderDetail"

Failing to add a key and value to a javascript object

I'm new to JavaScript and Node etc but enjoying the experience of developing - last serious development i did was in the 90s - I used to be a 370 assembler programmer back 30 years ago!
I've been stuck on this all day.
My issue is that I am trying to add a new element to the entries in an array of objects. I have simplified my code here in the hope that I am doing something blindingly stupid and obviously wrong though I have tried this in javascript in the browser and I know I am barking up the right tree.
What I am trying to do is add a new key/value pair to the collectibles returned. I have simplified the code here but in essence the value is coming for a different collection. the issue is that the lines that set the new keys are having no effect on my objects in the array collectibles. I have tried several methods all of which I believe should work.
I can read the key/values in the returned array of objects and I can also set existing keys to new values, but setting a new key is not working.
Here is my code:
var sendJsonResponse = function (res, status, content) {
res.status(status);
res.json(content);
};
var mongoose = require("mongoose");
var Coll = mongoose.model("collectible");
var Img = mongoose.model("image");
module.exports.collectiblesList = function (req, res) {
var firstImage_ids = [];
var imageDir = "https://s3.amazonaws.com/xxxxxxxxxxx/images/";
var defaultImage = imageDir + "default.jpg";
// get the collectibles
Coll.find(req.body).exec(function (err, collectibles) {
if (!collectibles) {
// not found
sendJsonResponse(res, 404, {"message": "no collectibles found"});
return;
}
if (err) {
console.log(collectible);
sendJsonResponse(res, 400, err);
return;
}
//found the collectibles
// now find the list of images we need to pull (each collectible can have multiple images
collectibles.forEach(function (collectible, index) {
if (collectible.image_ids) {
firstImage_ids.push(collectible.image_ids[0]);
collectibles[index].imageUrl = defaultImage; // this is the line that has no effect.
collectible.imageUrl = defaultImage; // tried this too.
collectible["imageUrl"] = defaultImage; // and this. :-(
console.log(collectible);
}
});
sendJsonResponse(res, 200, collectibles);
});
};
Using Postman to test this API. This is what is being returned:
[
{
"_id": "5a43c61134aaea2025158cab",
"name": "A-0_5",
"title": "Occoneechee Lodge 104: A-0_5",
"issueDate": null,
"quantity": null,
"event_id": null,
"type": "A - Arrowhead patches",
"tag_ids": [
"5a401a17b720186ab61c649e"
],
"description": "Elangomat, no name",
"organisation_id": "5a413340b720186ab61c661e",
"supercedes_id": null,
"sortName": "A-000.5",
"image_ids": [
"5a41685ab720186ab61c663d"
],
"deleted": false,
"schemaVersion": "1.0"
},
{
"_id": "5a43c63334aaea2025158cac",
"name": "A-1",
"title": "Occoneechee Lodge 104: A-1",
"issueDate": null,
"quantity": null,
"event_id": null,
"type": "A - Arrowhead patches",
"tag_ids": [
"5a401a17b720186ab61c649e"
],
"description": "Service",
"organisation_id": "5a413340b720186ab61c661e",
"supercedes_id": null,
"sortName": "A-001",
"image_ids": [
"5a41685ab720186ab61c663e"
],
"deleted": false,
"schemaVersion": "1.0"
}]
i.e. it contains no imageUrl keys.
thanks for the assist.
WWW
GT
I might have misunderstood. But if your issue is that collectibles[i].imageUrl is later on returning undefined/null, then i believe it's simply because you need to add
collectibles.save();
after setting the collectibles[i].imageUrl value. you can add that line after the foreach loop, before the json response.
collectibles.forEach(function (collectible, index) {
if (collectible.image_ids) {
firstImage_ids.push(collectible.image_ids[0]);
collectible.imageUrl = defaultImage;
}
});
collectibles.save(); //here, this saves the changes done to the mongoose object.
sendJsonResponse(res, 200, collectibles);
I solved it in the end after a lot of effort. This article explains (but i don't fully yet follow the explanation)
I found that the object has more metadata in it and the actual object is in _doc, so the first (and i suspect frowned upon solution) is to update the code to:
collectible._doc.imageUrl = defaultImage;
The better way was to simply add imageUrl to the mongoose model and leave _doc out of it. The issue there is that this is not a field i intend to populate in the mongoDB.

How to insert new child data in Firebase web app?

I am building a simple car database app. When a user adds a new car it creates the below JSON data with blank fields for the gallery:
{
"name": "Cars",
"gallery": [{
"img": "http://",
"title": "BMW"
}, {
"img": "http://",
"title": "Lexus"
}, {
"img": "http://",
"title": "Ferrari"
}],
"pageId": "23",
"storeURL": "/app/cars/gallery"
}
Now what I want to do in the app is if a user adds a new gallery image it should add new child after the last gallery picture. So after Ferrari it should insert a new object. I cannot seem to do this as every tutorial leads to a dead end and also the official Google docs specify that set() will replace all data so if you use update() it will add and in this case it does not add.
This code deletes all data:
function add(){
var data = [
{
title: 'Mercedes',
img: 'http://'
}
]
var postData = {
pageGallery: data
};
var updates = {};
updates['/app/cars/'] = postData;
firebase.database().ref().update(updates);
console.log('New car added');
}
And if I change and add the child:
firebase.database().ref().child('gallery').update(updates);
It does not do anything to do the data. Please can you help?
See this blog post on the many reasons not use arrays in our Firebase Database. Read it now, I'll wait here...
Welcome back. Now that you know why your current approach will lead to a painful time, let's have a look at how you should model this data. The blog post already told you about push IDs, which are Firebase's massively scalable, offline-ready approach to array-like collections.
As our documentation on reading and writing lists of data explains, you can add items to a list by calling push().
So if this creates a car:
function addStore(){
var rootRef = firebase.database().ref();
var storesRef = rootRef.child('app/cars');
var newStoreRef = storesRef.push();
newStoreRef.set({
name: "Cars",
"pageId": "23",
"storeURL": "/app/cars/gallery"
});
}
Then to add an image to the gallery of that store:
var newCarRef = newStoreRef.child('gallery').push();
newCarRef.set({
title: 'Mercedes',
img: 'http://'
})
This will add a new car/image to the end of the gallery (creating the gallery if it doesn't exist yet).
If somebody wants it With Error Handling :
var rootRef = firebase.database().ref();
var storesRef = rootRef.child('Lorelle/Visitors');
var newStoreRef = storesRef.push();
newStoreRef.set($scope.CarModal,
function(error) {
//NOTE: this completion has a bug, I need to fix.
if (error) {
console.log("Data could not be saved." + error);
Materialize.toast('Error: Failed to Submit' + error, 2000);
} else {
console.log("Data saved successfully.");
Materialize.toast('Data Submitted, Thank You.', 2000);
}
});
}

Cannot Read Property of Undefined error while using Web Sockets with React Native

I am new to React Native and Java Script development. I am trying to retrieve a JSON object and display it on client but I am getting "cannot read property of undefined" error. The same works fine when I am using "Fetch" instead of websockets. I am not able to figure out the issue.
I debugged the code and could find out that I do receive the JSON from the server.
Here is my client code:
fetchDataWithSockets()
{
var url='ws://localhost:3000/';
var ws = new WebSocket( url );
var object;
ws.onmessage = (e) => {
object = JSON.parse(e);
}
this.setState({
dataSource: this.state.dataSource.cloneWithRows(object.movies),
isLoading: false,
empty: false,
documents: object.movies
});
}
Object on Server:
var object = {
"title": "The Basics - Networking",
"description": "Your app fetched this from a remote endpoint!",
"movies": [
{ "title": "Star Wars", "releaseYear": "1977"},
{ "title": "Back to the Future", "releaseYear": "1985"},
{ "title": "The Matrix", "releaseYear": "1999"},
{ "title": "Inception", "releaseYear": "2010"},
{ "title": "Interstellar", "releaseYear": "2014"}
]
}
Any help would be appreciated :)
object is not completely available in the line this.setState.... You have to move your this.setState line inside the onmessage of the WebSocket. Your code will looks like this:
fetchDataWithSockets(){
var url='ws://localhost:3000/';
var ws = new WebSocket( url );
var object;
ws.onmessage = (e) => {
object = JSON.parse(e);
this.setState({
dataSource: this.state.dataSource.cloneWithRows(object.movies),
isLoading: false,
empty: false,
documents: object.movies
});
}
}

Categories

Resources