adding and reading a JSON asset in Flutter Web app - json

Got a problem reading an asset in Flutter web app. I've declared it in pubspec.yaml
But when I'm trying to load it with await rootBundle.loadString('test/sample_text.json'); I always get the same error Error while trying to load an asset: Failed to load asset at "assets/test/sample_text.json"
Never had such issue when developing for mobile

Assets in the web are placed under another assets/ directory, which results in the path being assets/assets/....
Create a simple function e.g. in lib/utils.dart:
import 'package:flutter/foundation.dart';
String path(str) {
return (kIsWeb) ? 'assets/$str' : str;
}
Wrap any path strings with this function, for example
AssetImage(path('assets/test/sample_text.json')).

the correct way to do this is packages/$your_package/assets/test/sample_text.json

Related

Using a relative path for File() in Flutter

I am working in Flutter and trying to open a json file in my assets folder. I found I can use the File() method, but it only seems to take an absolute path. Is there a way I can convert this to a relative path? I've tried using the relative path to the file already, but it returns an error saying no such file.
Here is the code so far. Basically I want to get the json file, and return it as a string (in the function readFileSync() below). Then I use that data to create a List object. If there's a better way to read a file into Flutter, I'm open to that too!
List<Answers> myFunction2() {
String arrayObjsText = readFileSync();
//print(arrayObjsText);
var tagObjsJson = jsonDecode(arrayObjsText)['tags'] as List;
var tagObjs =
tagObjsJson.map((tagJson) => Answers.fromJson(tagJson)).toList();
return tagObjs;
}
String readFileSync() {
String contents = new File(
'/Users/pstumbaugh/Documents/Computer Science/CS492 Mobile Dev/Dart-Flutter-CallMeMaybe/project3/assets/answers.json')
.readAsStringSync();
return contents;
}
I don't know much about how Futures work. I tried with those, but it seems like it always returns a Future and I'm not sure how to unpack that down to just a string without having to make everything async functions, which then led to problems when I try to get the List in my widgets on the main page...
You should to get assets not from relative path from your PC. When you install an app for a device or a emulator/simulator, it is can't access files on your computer. In few words, you can do it with loadString method from flutter/services.dart package (it is in Flutter SDK by default):
import 'package:flutter/services.dart' show rootBundle;
final data = rootBundle.loadString('assets/answers.json');
And make sure that you declared assets in pubspec.yaml config. Here is an official tutorial for how to work with assets.

Proper way to include lists and other external data inside a TypeScript React App

I created a React App using the create-react-app npm package. Everything works fine, however I'm not sure how to handle external files.
I created a POC that holds a json object of the entries for a select field. I can import the object and it works properly. However, I'm used to having files like this available on the server so that they can be edited without having to re-build the program.
I converted the file to a .json and I'm able to import it without a problem. However, if I try to move it to the "public" folder, I'm no longer able to import it. If it remains within the src folder it gets included within the bundle and I'm not able to edit it directly.
Is including the file within the bundle the standard way of handling data that can change (whether by requiring update or i18n)??? If not, how do I go about configuring the app to allow me to import it from the public folder once it's deployed?
This should work:
Add data.json to public directory and use fetch in componentDidMount
componentDidMount() {
fetch('data.json').then(data => {
data.json().then(response => {
console.log(response)
this.setState({ data }); // you can set data to state
});
})
}
content of data.json
{
"data": "some data"
}
If you are trying to use some external data e.g. from server, you should not import it like any other files (i.e. import a.js from './a') you should make HTTP request in order to retrieve these data

In Angular, imported json file as indexed type always return undefined

You will find instructions to reproduce on your own device at the bottom.
I have a basic Angular project I created using Angular CLI, running on TypeScript 3.1.3, with nothing much added aside a class and a json file.
I created a class ResourcesService with the following command with Angular CLI:
ng generate service Resources
I'm basically using it to load json files, as a mean of localising (instead of using Angular unfinished builtin internationalisation features).
The following is my class, as well as the json file:
ResourcesBundle.json
{
"label.changeLanguage": "Change language",
"label.education": "Education",
"label.experience": "Experiences",
"label.skills": "Skills",
"label.summary": "Summary",
"label.language.english": "English",
"label.language.french": "French"
}
resources.service.ts
import * as resources from '../assets/resources/ResourcesBundle.json';
#Injectable({
providedIn: 'root'
})
export class ResourcesService {
constructor() {}
public getString(label: string): string {
let resource: string = resources[label];
return resource;
}
}
Of course, in order to be able to import the json file that way, I've set "resolveJsonModule": true in tsconfig.json.
The service by itself is working properly. I can inject it and call the getString method, and it's running without any error.
However, no matter what value I pass to the getString method, the returned value is always undefined. I've even tried to hard code the value for label = 'label.summary', but it's still returning undefined. The only time it's working properly is when I write the string directly between the brackets:
let resource: string;
label = 'label.summary';
resource = resources[label]; // resource == undefined
resource = resources['label.summary']; // resource == 'Summary'
Within the TS on VSCode, the content of resources is as following:
label.changeLanguage
label.education
label.experience
label.language.english
label.language.french
label.skills
label.summary
When using console.log(resources), the console was displaying something like this on Firefox:
Object {
label.changeLanguage: "Change language"
label.education: "Education"
label.experience: "Experience"
label.language.english: "English"
label.language.french: "French"
label.skills: "Skills"
label.summary: "Summary"
}
So the json is properly loaded, but it can only be used with hard coded string.
The only other solution I found was to give up the json file and initialise an indexed type directly in the code:
private resources: { [key: string]: string } = {
'label.changeLanguage': 'Change language',
'label.education': 'Education',
'label.experience': 'Experiences',
'label.skills': 'Skills',
'label.summary': 'Summary',
'label.language.english': 'English',
'label.language.french': 'French'
};
However, I don't think that's a good approach, at all...
In the case of the imported json file, why does it always return undefined when I use a variable? Or otherwise, why does it work only with a hard coded string between the brackets?
Edit:
You will find below a stackblitz link to a demo project:
https://stackblitz.com/edit/angular-h2aspf?file=tsconfig.json
If you run it on the browser, it will work properly (the console will properly display Change language).
However, if you download it and run it locally, you will notice that the console will display undefined instead.
To run it locally:
You must have npm and Angular CLI
Download and unzip the stackblitz demo in a folder
Run npm i in the project folder
Run ng serve --open
Open the console on your browser, it should be displaying undefined, instead of the expected value (Change language on stackblitz)
Edit:
According to a comment on the Angular CLI issue, a workaround is to set "esModuleInterop": true in tsconfig.json, and to change the import statement from:
import * as resources from '../assets/resources/ResourcesBundle.json';
To this:
import resources from '../assets/resources/ResourcesBundle.json';
Original answer:
After checking multiple times on different devices, I think this is a bug directly related to Angular (current version: 7.0.2).
To take the example I gave in the question again:
https://stackblitz.com/edit/angular-h2aspf?file=tsconfig.json
On the browser, this demo is outputting Change language on the console.
On locale device:
Download and unzip the stackblitz demo in a folder
Run npm i in the project folder
If you run with ng serve, you will notice undefined in the web browser console
Stop Angular, then run again with ng serve --prod. The web browser console is now properly outputting Change language
I've opened the following issues for Angular and Angular CLI projects on GitHub for this problem:
Angular: Issue #26785: Imported json file as indexed type always giving undefined when Angular is not running in production mode
Angular CLI: Issue #12781: Imported json file as indexed type always giving undefined, but not when running ng serve --prod

JSON - Blender & ThreeJS - Unexpected token < in JSON at position 0

I have exported a 3D model from Blender using the io_three addon.
Now I am trying to load this model into ThreeJS using code like this.
import React, { Component } from 'react';
import * as THREE from 'three';
var loader = new THREE.JSONLoader();
loader.load('./making_a_face10.json', handle_load);
I am consistently getting the same error message.
Unexpected token < in JSON at position 0
I have tried using the THREE.ObjectLoader() and also this option https://github.com/tweedegolf/parsed-model, but it keeps saying error in position 0 of JSON.
As a side note, I can access the JSON like this:
var JSONdata = require('./making_a_face10.json');
That does expose data inside the JSON, but I want the ThreeJS loader to work.
Then I found this example https://threejs.org/examples/#webgl_loader_json_blender and when I went to view the source code it shows that the 'model' is being imported as a .js file??, i.e. they are loading it like this:
loader.load( 'models/animated/monster/monster.js', function ( geometry, materials )...
There is ample material to explain what I want to do but none of it points to loading the model as a .js file.
two more notes - the format of my JSON file looks extremely like this https://github.com/mrdoob/three.js/blob/master/examples/models/animated/monster/monster.js and I am running a local server using npm start
If any whiz kid could help me out I would be extremely grateful.
SOLVED
In the React project folder. The .JSON file was in my /src folder. It should have been in my /public folder.
As Kryten mentioned in the comments.. Your load is failing. The first character in your JSON file is not a '<'. That looks like an XML response failure header.
The THREE loader uses XMLHTTPRequest internally... you could try loading your JSON directly with XMLHTTPRequest and then log the output to see what the error is..

NodeJS Photoshop PSD parser toJSON() has no method

Im using https://github.com/meltingice/psd.js to parse a PSD file in node,
I see that toJSON() can be used, https://github.com/won21kr/psd.js-1
but when I try to use on a simple hello world after installing the module,
npm install psd
toJSON() gives me error:
info = psd.toJSON();
^ TypeError: Object # has no method 'toJSON'
normal log works fine,
var PSD = require('psd');
var psd = PSD.fromFile("AntoineVeglas_Filter_BW.psd");
psd.parse();
node = psd.tree().descendants()[0];
console.log(node);
info = psd.toJSON();
how to parse to valid json my psd tree object? cheers
You are aware that toJSON function is in a fork project of the original right? So if you install psd using npm, you will get the original project which has no toJSON function.
You should checkout the fork (won21kr) and either put it in your node_modules folder, or put it somewhere else and access the js file with a relative module path notation: require('./psd-fork/index.js').
change psd.tree().descendants()[0]; to psd.tree().descendants()[0].export();