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.
Related
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
In ASP.NET Core, the JsonConfigurationProvider will load configuration from appsettings.json, and then will read in the environment version, appsettings.{Environment}.json, based on what IHostingEnvironment.EnvironmentName is. The environment version can override the values of the base appsettings.json.
Is there any reasonable way to preview what the resulting overridden configuration looks like?
Obviously, you could write unit tests that explicitly test that elements are overridden to your expectations, but that would be a very laborious workaround with upkeep for every time you change a setting. It's not a good solution if you just wanted to validate that you didn't misplace a bracket or misspell an element name.
Back in ASP.NET's web.config transforms, you could simply right-click on a transform in Visual Studio and choose "Preview Transform". There are also many other ways to preview an XSLT transform outside of Visual Studio. Even for web.config parameterization with Parameters.xml, you could at least execute Web Deploy and review the resulting web.config to make sure it came out right.
There does not seem to be any built-in way to preview appsettings.{Environment}.json's effects on the base file in Visual Studio. I haven't been able to find anything outside of VS to help with this either. JSON overriding doesn't appear to be all that commonplace, even though it is now an integral part of ASP.NET Core.
I've figured out you can achieve a preview with Json.NET's Merge function after loading the appsettings files into JObjects.
Here's a simple console app demonstrating this. Provide it the path to where your appsettings files are and it will emit previews of how they'll look in each environment.
static void Main(string[] args)
{
string targetPath = #"C:\path\to\my\app";
// Parse appsettings.json
var baseConfig = ParseAppSettings($#"{targetPath}\appsettings.json");
// Find all appsettings.{env}.json's
var regex = new Regex(#"appsettings\..+\.json");
var environmentConfigs = Directory.GetFiles(targetPath, "*.json")
.Where(path => regex.IsMatch(path));
foreach (var env in environmentConfigs)
{
// Parse appsettings.{env}.json
var transform = ParseAppSettings(env);
// Clone baseConfig since Merge is a void operation
var result = (JObject)baseConfig.DeepClone();
// Merge the two, making sure to overwrite arrays
result.Merge(transform, new JsonMergeSettings
{
MergeArrayHandling = MergeArrayHandling.Replace
});
// Write the preview to file
string dest = $#"{targetPath}\preview-{Path.GetFileName(env)}";
File.WriteAllText(dest, result.ToString());
}
}
private static JObject ParseAppSettings(string path)
=> JObject.Load(new JsonTextReader(new StreamReader(path)));
While this is no guarantee there won't be some other config source won't override these once deployed, this will at least let you validate that the interactions between these two files will be handled correctly.
There's not really a way to do that, but I think a bit about how this actually works would help you understand why.
With config transforms, there was literal file modification, so it's easy enough to "preview" that, showing the resulting file. The config system in ASP.NET Core is completely different.
It's basically just a dictionary. During startup, each registered configuration provider is run in the order it was registered. The provider reads its configuration source, whether that be a JSON file, system environment variables, command line arguments, etc. and builds key-value pairs, which are then added to the main configuration "dictionary". An "override", such as appsettings.{environment}.json, is really just another JSON provider registered after the appsettings.json provider, which obviously uses a different source (JSON file). Since it's registered after, when an existing key is encountered, its value is overwritten, as is typical for anything being added to a dictionary.
In other words, the "preview" would be completed configuration object (dictionary), which is composed of a number of different sources, not just these JSON files, and things like environment variables or command line arguments will override even the environment-specific JSON (since they're registered after that), so you still wouldn't technically know the the environment-specific JSON applied or not, because the value could be coming from another source that overrode that.
You can use the GetDebugView extension method on the IConfigurationRoot with something like
app.UseEndpoints(endpoints =>
{
if(env.IsDevelopment())
{
endpoints.MapGet("/config", ctx =>
{
var config = (Configuration as IConfigurationRoot).GetDebugView();
return ctx.Response.WriteAsync(config);
});
}
});
However, doing this can impose security risks, as it'll expose all your configuration like connection strings so you should enable this only in development.
You can refer to this article by Andrew Lock to understand how it works: https://andrewlock.net/debugging-configuration-values-in-aspnetcore/
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
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..
In my windows store app using the Visual Studio 2012 designer I want to be able to load some model objects for the designer. I've done this plenty of times before where I supply a xaml file using the ms-appx:/// uri without error. However, for this project I need to be able to instantiate a class and have it convert raw xml of a different format into my model objects.
I'm using the following xaml to instantiate my class for the designer:
d:DataContext="{Binding Source={d:DesignInstance Type=model:Walkthroughs, IsDesignTimeCreatable=True}}"
In my Walkthroughs class had code that did this initially:
public Walkthroughs()
{
if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
AppDataLoader.LoadWalkthroughs(this, XDocument.Load("ms-appx:///SampleData/walkthroughs.xml"));
}
I first ran into an issue where the XDocument.Load did not understand the ms-appx:/// uri so I modified my code to something very simplistic:
AppDataLoader.LoadWalkthroughs(this, XDocument.Load(#"C:\walkthroughs.xml"));
Now I get access to path '' is denied.
I've tried several directories as well to no avail. I'm even running Visual Studio as an Administrator. If I remove the prefix altogether I get the following error:
Could not find file 'C:\Users\{me}\AppData\Local\Microsoft\VisualStudio\11.0\Designer\ShadowCache\omxyijbu.m4y\yofsmg1x.avh\walkthroughs.xml'.
Has anyone been able to load files from the file system when the designer instantiates objects?
Thanks,
-jeff
XDocument.Load(string uri) seems to have problems with loading Project resources from ms-appx:/
Regarding your second approach: Direct access to "C:" is not permitted. Ther is only a handful of special folders that you can access. Check out my workaround for this (my xml file is within the Assets folder of my project:
var storageFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
storageFolder = await storageFolder.GetFolderAsync("Assets");
var xmlFile = await storageFolder.GetFileAsync("data.xml");
var stream = await xmlFile.OpenReadAsync();
var rdr = new StreamReader(stream.AsStream(), System.Text.Encoding.GetEncoding("ISO-8859-1")); //needed if you have "ä,ß..." in your xml file
var doc = XDocument.Load(rdr);