I want to read a json file which is present locally in my system, in my polymer element. Currently i have put the json structure in task property of my element( as a first step).I am using 'dom-repeat' to parse through the json. But still cannot see anything in output.
<ul>
<template is="dom-repeat" items="{{items}}">
<li><span>{{item}}</span></li>
</template>
<template is="dom-repeat" tasks="{{task}}">
<li><span>{{task.task.name}}</span></li>
</template>
</ul>
Above is my !-template-! of the polymer element. Where i am trying to read an array i.e {{items}} and a json i.e {{task}}
Below is the script :
<script>
(function() {
'use strict';
Polymer({
is: 'my-list',
properties: {
items: {
type: Array,
notify: true
},
task:{
type: Array,
value: function () { return []; } // Default value
}
},
ready: function() {
this.items = [
'Responsive Web App boilerplate',
'Iron Elements and Paper Elements',
'End-to-end Build Tooling (including Vulcanize)',
'Unit testing with Web Component Tester',
'Routing with Page.js',
'Offline support with the Platinum Service Worker Elements'
];
this.task=[{
"task": {
"name": "Fan",
"rules": [{
"name": "Check Blades",
"id": "1",
"steps": [{
"name": "Check motor",
"operator": "OR",
"number": "1",
"substeps": [{
"name": "SubStep1",
"function": "code",
"expression": "(FAULT_CODE) == {err05,err07,err06}",
"number": "1",
"timeperiod": "86400000"
}]
}]
}]
}
}];
}
});
})();
I am able to see the array content i.e this.items but not the json contents. COuld anyone tell me where am I going wrong ? Below is the screenshot of the output where you can see the {{items}} but no {{task}} details.
The browser doesn't allow to read files that are locally on your system. The only thing you can do is to provide a file input that allows to choose files using a file picker and then read them from there. You can read them from your local system if the web server runs on your local system and serves that file to clients.
this.task is an array and so you'd need to use a computed binding to access its values.
See the relevant section in the docs for more info on how to do this.
Related
I am using a rest API, sending a GET request and getting the following JSON structure as a result:
{
"Id": "Sample Id",
"Attributes": {
"ReadOnly": false
},
"Children": [
{
"Id": "Sample Id1",
"Attributes": {
"ReadOnly": false
},
"Children": [
{
"Id": "Sample Id2",
"Attributes": {
"ReadOnly": false
}
}
]
},
{
"Id": "Sample Name2",
"Attributes": {
"ReadOnly": false
},
"Children": [
{
"Id": "Sample Id2",
"Attributes": {
"ReadOnly": false
}
}
]
}
]
}
It is basically a file system structure. So it is possible to have N objects(Id, Attributes{}, Children[]) in the root as well as in any other level of the structure.
Trying to explain a little bit better, the root node has its attributes and an array of N children that have its attributes and another Array of N children and so on...
How would be the correct way to handle this situation?
I have created a flat interface structure, looking basically like that:
export interface Hana{
Id: string,
Attributes: {
ReadOnly: string
}
}
I have also created a service and a component as follows:
Service
getHanaStructure(): Observable<Hana[]> {
const hanaStructs = this.http.get<Hana[]>(this.apiUrl);
this.messageService.add('HanaService: fetched struct');
return hanaStructs;
Component
hanaStructures$: Observable<Hana[]>;
getHanaStructure() : void {
this.hanaStructures$ = this.hanaService.getHanaStructure().pipe(map(data=> _.toArray(data)));
}
In order to show the data my HTML template looks like that:
<ul *ngIf="hanaStructures$ | async as hanaStructures else noData">
<li *ngFor="let hana of hanaStructures">
{{hana}}
</li>
</ul>
<ng-template #noData>No Data Available</ng-template>
The first problem is that I don't know to access the information by its key, I can just list their values. When I try something like {{ hana.Id }} instead of just {{ hana }} I got: *
"Property 'Id' does not exist on type 'Hana'"
The second issue is that I can only manage to list the first level data. I don´t know how access the Children of the Children of Children...
I am sure that the API is returning everything I need, but unfortunately I don´t know how to solve the problem.
Thanks,
Filipe
At first I would define the "Children" property in your Hana Interface as List of "Hana" Interfaces (This has some similarity with a resursive approach). Afterwards I would create a seperate Component, which gets displayed if you loop through the first layer of your children. This component should contain a loop of its own to loop through deeper nested components recursively.
Hope this was understandable and helps you. =)
I am having a strange issue with an Angular 7.1.1 and Electron 4.1.4 project.
Data Flow:
Angular Component "Report Builder" collects report configuration options from a FormGroup and FormControl validated form and sends data to docx-templater.service
User Button triggers createReport() function
When submitting options for a complete report, the createReport() function calls dataService's fnGetCompleteControlList() which returns properly configured JSON asynchronously.
with a .then() function after the async data retrieval, the createReport() function combines the output directory which is part of the configuration form and sends both to the docx-templater.service's createCompleteDocument() function. Once the promise is returned it updates the UI.
Angular Service "docx-templater"'s createCompleteDocument function passes the data and folder values to the ipcRenderer.send for the electron "writeCompleteDocument" channel and returns a promise.
In my main.ts, I have an ipcMain.on for the "writeCompleteDocument" channel that passes the data to a write-docx function for processing that data into a word document.
Problem:
When the data gets to my write-docx function it is missing a sub array of objects that are essential to the export process.
I have verified that the data is perfect in the Chrome Developer Tools console of electron at the moment just before it sends the data to the docx-templater.service and just before that service sends it to the ipcRenderer (meaning my data service and Report Builder functions are working as designed). When I check the data in the main.ts by saving the data off to a JSON file it is missing the controls sub array within the second object of the JSON only. The controls sub array shows up in the first object as expected.
I will note that what is coming out of the ipcMain function is a properly formed JSON file so it has really just excluded the "controls" sub array and is not truncating due to memory or buffer limits or anything like that.
report-builder.component.ts
createReport() {
if (this.reportBuilderFG.get('allControls').value) {
this.db.fnGetCompleteControlList()
.then((groups: Group[]) => {
this.word.createCompleteDocument(groups, this.reportBuilderFG.get('folder').value + '\\filename.docx')
.then(() => {
this.openSnackBar(this.reportBuilderFG.get('folder').value + '\\filename.docx created successfully');
});
});
} else {
// Do other stuff
}
docx-templater.service.ts
createCompleteDocument(data, folder: string): Promise<boolean> {
return new Promise(resolve => {
console.log(data) <=== Data is perfect here.
ipcRenderer.send('writeCompleteDocument', {data: data, folder: folder});
resolve();
});
}
main.ts
import { writeCompleteDocument } from './node_scripts/write-docx';
ipcMain.on('writeCompleteDocument', (event, arg) => {
fs.writeFileSync("IPCdata.json", arg.data); // <==== Part of the data is missing here.
writeCompleteDocument(arg.data, arg.folder);
});
Good Data Example (some keys and objects excluded for brevity)
[
{
"name": "General Security",
"order": 1,
"subgroups": [
{
"_id": "GOV",
"name": "Governance",
"order": 1,
"controls": [
{
"group": "GS",
"subgroup": "GOV",
"active": true,
"printOrder": 1,
"name": "This is my GS control name",
"requirements": [
{
"id": "SA01",
"active": true,
"order": 1,
"type": "SA",
"applicability": [
"ABC",
"DEF",
"GHI"
],
},
{ ... 3 more }
],
"_id": "GSRA-03",
"_rev": "1-0cbdefc93e56683bc98bae3a122f9783"
},
{ ... 3 more }
],
"_id": "GS",
"_rev": "1-b94d1651589eefd5ef0a52360dac6f9d"
},
{
"order": 2,
"name": "IT Security",
"subgroups": [
{
"_id": "PLCY",
"order": 1,
"name": "Policies",
"controls": [ <==== This entire sub array is missing when exporting from IPC Main
{
"group": "IT",
"subgroup": "PLCY",
"active": true,
"printOrder": 1,
"name": "This is my IT control name",
"requirements": [
{
"id": "SA01",
"active": true,
"order": 1,
"type": "SA",
"applicability": [
"ABC",
"DEF",
"GHI"
],
}
],
"_id": "GSRA-03",
"_rev": "1-0cbdefc93e56683bc98bae3a122f9783"
}
}
],
"_id": "IT",
"_rev": "2-e6ff53456e85b45d9bafd791652a945c"
}
]
I would have expected the ipcRenderer to pass a JSON exactly as it is to the ipcMain.on function, but somehow it is trimming part of the data. I have even tried strigifying the data before sending it to the renderer and then parsing it on the other side but that did nothing.
Could this be an async thing? I am at a loss of where to go next to debug and find what idiot mistake I made in the process.
Also, I realize that the above data flow seems overly complex for what I am doing, and that I can probably do it easier, but it makes sense (kinda) for the way the whole application is structured so I am going to go with it if I can squash this bug.
Looks like your createCompleteDocument() function is set up incorrectly. A quick search showed me that ipcRenderer is an async function, but you are responding to it (almost) synchronously.
You have the following, which is (probably) incorrect (actually it's definitely incorrect, because you've typed typed the return as Promise<boolean> when it is Promise<void>):
createCompleteDocument(data, folder: string): Promise<boolean> {
return new Promise(resolve => {
ipcRenderer.send('writeCompleteDocument', {data: data, folder: folder});
resolve();
});
}
ipcRenderer#send() is async but you are calling resolve() immediately afterwards without waiting for the function to resolve. This probably explains why adding the setTimeout() is fixing the problem for you. Looking at the ipcRenderer docs, the following probably does what you want:
createCompleteDocument(data, folder: string): Promise<Event> {
return new Promise(resolve => {
ipcRenderer.once('writeCompleteDocument', resolve);
ipcRenderer.send('writeCompleteDocument', {data: data, folder: folder});
});
}
Looks like the callback is passed an Event object.
Another option would be to simply replace ipcRenderer#send() with ipcRenderer#sendSync() in your original code, but as pointed out in that method's documentation :
Sending a synchronous message will block the whole renderer process, unless you know what you are doing you should never use it.
Making use of ipcRenderer#send() and ipcRenderer#once() is almost definitely the way to go.
Seperately, you can clean up the code by switching to async/await functions. For example:
async createReport(): Promise<void> {
if (this.reportBuilderFG.get('allControls').value) {
const groups: Group[] = await this.db.fnGetCompleteControlList();
await this.word.createCompleteDocument(
groups,
this.reportBuilderFG.get('folder').value + '\\filename.docx'
);
// Unclear if this function is actually async
await this.openSnackBar(
this.reportBuilderFG.get('folder').value +
'\\filename.docx created successfully'
);
} else {
// Do other stuff
}
}
I was able to solve this by adding a 1000 ms timeout after my fnGetCompleteControlList() data pull in the report-builder.component.ts. It seems like I have a lot more work todo with learning async functions. :-(
report-builder.component.ts
createReport() {
if (this.reportBuilderFG.get('allControls').value) {
this.db.fnGetCompleteControlList()
.then((groups: Group[]) => {
setTimeout(() => {
this.word.createCompleteDocument(groups, this.reportBuilderFG.get('folder').value + '\\filename.docx')
.then(() => {
this.openSnackBar(this.reportBuilderFG.get('folder').value + '\\filename.docx created successfully');
});
}, 1000);
});
} else {
// Do other stuff
}
Trying to create a website that takes in information from an API, however I don't really understand how to do it seeing that I need all results grouped up and the API I've created almost never gives a response with the same amounts of objects. So the question is, seeing that I use vue.js and axios is there any way to loop through the json objects to show each of the objects in a seperate ? I manage to do it when there are a specified amounts, but I want to make it dynamic so I don't hardcode into the variables what part of the response I need to set to each variable.
UPDATE: I've tried to use v-for, but seeing that I need to have the output quite structured it doesn't really help, I've also tried Nested V-for loops, once again I can't get the accuracy that I'm looking for.
UPDATE2: Also should be added, when I say JSON object I actually ment js object. the json.parse() has been used on the json.
UPDATE3: Updated the JSON to actual data that I'm using for the application.
Every div need a lemma, a paradigm tagset, inflection tagset and inflectionForms and a table for all the meanings. Just need meaning not meaningText. TranslationId is not important. The JTranslate that wraps every object will be removed, just kinda tired of the Java at the moment, will do that later today and do the adjustments on the vue projects aswell regarding that deletion.
Actually your json format is invalid
{
"object1":{
"name": "test",
"data": "test"
},
"object2":{
"name": "test2",
"data": "test2"
},
"object3":{
"name": "test2",
"data": "test2"
}
}
it should be like above and use JSON.parse() method to simply convert the json to javascript object
Valid Object:
var objects = {
"object1":{
"name": "test",
"data": "test"
},
"object2":{
"name": "test2",
"data": "test2"
},
"object3":{
"name": "test2",
"data": "test2"
}
}
for iteration use
<div v-for="(object,index) in objects" :key="index">
{{object}}
</div>
The correct object as an array:
test: [
{
object1: {
name: 'name1',
data: 'content1'
}
},
{
object2: {
name: 'name1',
data: 'content1'
}
},
{
object3: {
name: 'name3',
data: 'content3'
}
}
]
can be mapped as a computed property inside the script tages:
computed: {
mappedTest() {
return this.test.map(entry => {
const key = Object.keys(entry)[0];
return { name: entry[key].name, data: entry[key].data };
});
}
},
and call it inside the template
<div
v-for="testObject in mappedTest"
:key="testObject"
>
name: {{testObject.name}}; data: {{testObject.data}}
</div>
I was very tired when I asked this question, apparently I did everything wrong. Can easily be solved by nested v-for loops.
I am developing a simple TODO manager application in Ember using ember-data and JSONAPISerializer.
I have the following model which represents a task
app/model/task.js
export default DS.Model.extend({
title: DS.attr ('string'),
description: DS.attr ('string'),
isComplete: DS.attr ('boolean')
});
The corresponding JSON data from back-end looks like this
{
"data": {
"id": "1",
"type": "task",
"attributes": {
"title": "Complete Ember TODO manager application",
"description": "Build a simple Ember application for easily managing tasks",
"is_complete": "false"
}
}
}
I have added editing support for task using the following controller.
app/controllers/tasks/task.js
import Ember from 'ember';
export default Ember.Controller.extend({
isEditingTask: false,
actions: {
startEditTask() {
this.set('isEditingTask', true);
},
doneEditTask(id) {
this.set('isEditingTask', false);
this.get('model').save();
},
}
});
When not in editing mode, an edit button is shown, which triggers the startEditTask action. When in editing mode a done button is show which triggers the doneEditTask action.
I have verified that the done button does generate a PATCH request.
The problem is that the JSON sent to the back-end has the type as tasks not task. Is this expected?
JSON sent with PATCH request is as follows
{
"data": {
"id": "1",
"type": "tasks",
"attributes": {
"title": "Allow editing of a task",
"description": "Allow the user to change various properties of a task",
"is_complete": "true",
}
}
Probably it's too late, but I've faced similar issue today and as far as I see based on these:
JSON API response and ember model names
http://emberjs.com/api/data/classes/DS.JSONAPISerializer.html
http://jsonapi.org/format/#crud-updating
If endpoint is plural (eg. api/tasks), ember expects the type to be plural as well
In the app we're developing, we create all the JSON at the server side using dinamically generated configs (JSON objects). We use that for stores (and other stuff, like GUIs), with a dinamically generated list of its data fields.
With a JSON like this:
{
"proxy": {
"type": "rest",
"url": "/feature/163",
"timeout": 600000
},
"baseParams": {
"node": "163"
},
"fields": [{"name": "id", "type": "int" },
{"name": "iconCls", "type": "auto"},
{"name": "text","type": "string"
},{ "name": "name", "type": "auto"}
],
"xtype": "jsonstore",
"autoLoad": true,
"autoDestroy": true
}, ...
Ext will gently create an "implicit model" with which I'll be able to work with, load it on forms, save it, delete it, etc.
What I want is to specify through a JSON config not the fields, but the model itself. Is this possible?
Something like:
{
model: {
name: 'MiClass',
extends: 'Ext.data.Model',
"proxy": {
"type": "rest",
"url": "/feature/163",
"timeout": 600000},
etc... }
"autoLoad": true,
"autoDestroy": true
}, ...
That way I would be able to create a whole JSON from the server without having to glue stuff using JS statements on the client side.
Best regards,
I don't see why not. The syntax to create a model class is similar to that of store and components:
Ext.define('MyApp.model.MyClass', {
extend:'Ext.data.Model',
fields:[..]
});
So if you take this apart you could call Ext.define(className,config);
where className is a string and config is a JSON object and both are generated on the server.
There's no way to achieve what I want.
The only way you can do it is by means of defining the fields of the Ext.data.Store and have it to generate the implicit model by using the fields configuration.