Reputation: 6670
I have an application that must run without serving. A html file is generated and everything it needs is inside. I'm using jquery with bootstrap (I just import them directly in the html), but I would like to change to Angular 8, for instance, because the project is getting bigger. I believe that Angular makes http requests to read files, templates, maybe routing etc, and as we know, browsers does not allow reading files without a http server.
QUESTION: Is there any angular/ng-cli build instruction or development guidelines (like not lazy loading modules, for instance) that allows me to build an offline standalone application (just open a html file)?
When I build the app with ng build --prod
, the generated files still need a server. I get the following error on chrome:
Not allowed to load local resource
(Some edits to make it more clear)
I'm in a very restrictive and diversified OS business environment where generate a binary won't be possible. Everyone has a browser in their computer and not everyone has internet access. Then running the html offline is mandatory.
This is the process: I generate a html file, then I send this html file for people who does not have internet access, then they open it in a browser just clicking on it. There's no http server where they can access the generated html.
Upvotes: 1
Views: 2386
Reputation: 1131
If I properly understand what you're trying to ask, once Angular is packaged, you do not need anything to run it, hence why you can bundle it and serve it up as a static website in places like Amazon Web Services S3 buckets ("serverless"). You can read from JSON files in a disconnected environment, so long as they are local to the project. It might look something like the following:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { IDataFile } from '../interfaces/data-file.interface';
@Injectable({
providedIn: 'root'
})
export class MyDataService {
static data: IDataFile;
constructor(private http: HttpClient) { }
load() {
const jsonFile = `assets/data/my-data.json`;
return new Promise<void>((resolve, reject) => {
this.http.get(jsonFile).toPromise().then((response: IDataFile) => {
MyDataService.data = <IDataFile>response;
resolve();
}).catch((response: any) => {
reject(`Could not load file '${jsonFile}': ${JSON.stringify(response)}`);
});
});
}
}
Then you could load your data into the service at startup by adding a method into your app.module.ts after your imports and then adding your service under providers:
export function initializeApp(data: MyDataService ) {
return () => data.load();
}
...
providers: [
MyDataService ,
{
provide: APP_INITIALIZER,
useFactory: initializeApp,
deps: [MyDataService], multi: true
},
]
You could then utilize your service anywhere in your application with MyDataService.data.somedata
.
The major caveat to all of this is that as I said, you can READ from a JSON file, but you cannot write back to it, so this would not be data you could update except in memory (data would be non-persistent and would reset on reload). You could combat this to some extent if you used local sessionStorage or localStorage, or even cookies, and then overwrite your preloaded data if your local storage was populated; but in this case, there would be no central management of the data, so it would have to be a specific use case.
If you wish to write to files on the file system, I would look at a desktop application wrapper for your Angular application like Electron (https://electronjs.org/), but this would require an install for your users.
Upvotes: 2