unable to retrieve json data from assets folder using angular - javascript

what i want : i have a config file where it contains some urls in .json file stored in asset folder now instead of loading environments.prod or .ts i want to load my json file config and basing on that i want run my application
what i did
below is my json file which i placed asset folder
{
"baseUrl": "https://jsonplaceholder.typicode.com/",
"baseUrl2": "https://reqres.in/api/users"
}
now i created a ConfigServiceService.ts fpr storing config file
public _config: Object;
constructor(public http:Http) { }
getData(){
debugger;
return this.http.get("./assets/config.json").pipe(map(res => res.json()));
}
after this i create a ServiceProviderService.ts for calling the service file
configData:any;
constructor(public http:Http,public config:ConfigServiceService) {
}
jsonData(){
debugger;
return this.configData;
}
ngOnInit(){
debugger;
this.config.getData().subscribe(res =>{
console.log(res);
this.configData = res;
});
}
now i am calling the app.component.ts
title = 'sample';
constructor(public serv :ServiceProviderService){
this.serv.jsonData();
}
now my issue is i am not able to get the json data and if i am putting the logic which is there is ngoninit in ServiceProviderService.ts file if put it in constructor then i am getting undefined
note : here if there are more that once url then each url is distributed to various seperate service file suppose base1 url for 1 service file ans base2 url for another file how can i achieve that

To access the assets folder. Make sure angular.json has a reference under
architect --> build -->options to the directory where the file is stored:
"assets": [
"src/favicon.ico",
"src/assets"
],

Try giving it an absolute url and it should work
Here, give this a try:
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable()
export class ConfigService {
constructor(private http: HttpClient) { }
getData() {
return this.http.get('/assets/config.json');
}
}
Here's a Working Sample StackBlitz for your ref.

In Angular only components have lifecycle hooks (like ngOnInit, ngOnDestroy etc), services haven't. In services you should use their constructor instead.

Related

crud operation on json file without json server in Angular [duplicate]

I want to update my JSON file which I have placed in my assets folder, so If I am updating just one property of my JSON object so it should update that property only, without affecting any other properties value:
Let the sample code be :
loginInterface.ts
export interface loginModel {
Email: string;
Password: string;
}
login.component.ts
import { Component, OnInit } from '#angular/core';
import { Observable } from 'rxjs';
import { HttpClient } from '#angular/common/http'
import { loginModel } from './loginModel'
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
private _jsonURL = 'assets/Login.json';
private login: Array<loginModel>;
constructor(
private http: HttpClient) {
this.login = new Array<loginModel>();
}
ngOnInit() {
this.getLoginData();
}
getLoginData() {
this.http.get<loginModel[]>(this._jsonURL).subscribe(data => {
this.login = data;
console.log(this.login);
return this.login;
});
}
UpdateLoginData() {
// How to proceed on this one??
}
}
login.component.html
<div *ngFor = "let log of login">
{{log.Email}}
<input [ngModel]="log.Password">
</div>
<button (click)="UpdateLoginData()">Update</button>
This is just an example.
So if I am changing password at one place and clicking on update button , then it should update password of that specific Email only and I don't want to replace the whole file with new JSON object just for updating a single value, is this possible?
You can't do any file operation using just angular framework. You need server side implementation to achieve this. If you are not familiar with server side programming you can try using in memory angular database api.
https://www.npmjs.com/package/angular-in-memory-web-api
You can't change the content of JSON file directly through angular, you need the Backend in order to reflect the change on that JSON file.
No! You cannot change a file’s content using Angular. It is a file I/O operation that is handled by a backend framework/language (for example Node.JS) having file system API. You can create a RESTful API to modify the contents of the file and make an HTTP call from Angular.
In json server you can update using put method
//somewhat like given below
this.http.put(this._jsonURL+this.login[0].id,this.login[0]).subscribe();

How to change one server URL to another server URL, if the server is down in angular6

I have 4 servers with different URLs, i want to change one server URL to another server URL if server is down in angular 6 application, if anyone knows please help me.
Consider i have 4 servers with different URLs(1st,2nd,3rd and 4th), here 1st server is having more priority and i want to make it has default. and my question is how to change 1st server URL to 2nd server URL as same as for 3rd and 4th also, if servers are down. Any help would be appreciated and thanks in advance.
service.ts file
firstserver ="http://111.121.1.342:8001/rest/formalities";
secondserver="http://111.121.1.342:8002/rest/formalities";
thirdserver="http://111.121.1.342:8003/rest/formalities";
fourthserver="http://111.121.1.342:8004/rest/formalities";
validateUserDetails(employeeDetails): Observable<any> {
console.log(serversurl);
return this._httpClint.post(serversurl(would be first/second/third/fourth server), employeeDetails);
}
here i have to check first server URL is up or down then apply to server URL which one is up.
Expected result:
I should be able to change one server URL to another server URL based on up and down condition.
for my above problem i got solution like in below, for that we have to take help from JAVASCRIPT.
step 1:->
create env.js file in the directory of index.html, like in below.
(function (window) {
window.__env = window.__env || {};
// API url
window.__env.apiUrl = "http://RestWebService";
// Whether or not to enable debug mode
// Setting this to false will disable console output
window.__env.enableDebug = true;
}(this));
the meaning of above env.js file is just we are creating one global variable called apiUrl, to store our server URL. So that we can access that variable globally. Next, we add a element to the section in our index.html to load env.js before Angular is loaded:
<html>
<head>
<!-- Load environment variables -->
<script src="env.js"></script>
</head>
<body>
...
<!-- Angular code is loaded here -->
</body>
</html>
By default, JavaScript files such as env.js are not copied to the output directory when we build our application.
To make sure that the file is copied to the output directory when we run ng build or ng serve, we must add it to the assets section of our application's build configuration in angular.json:
angular.json file
{
"projects": {
"app-name": {
"architect": {
"build": {
"options": {
"assets": [
"src/favicon.ico",
"src/assets",
"src/env.js"
]
}
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
// ...
}
}
}
}
}
}
}
step 2:->
Create one service in the name of any, in my case i created it as env.service.ts in the directory of app.module.ts.
this is a service file will be used to take our server URL value, which is stored in apiUrl(env.js file).
env.service.ts
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class EnvService {
// The values that are defined here are the default values that can
// be overridden by env.js
// API url
public apiUrl = '';
// Whether or not to enable debug mode
public enableDebug = true;
constructor() {
}
}
step 3:->
Create on service provider file in the same directory of env.service.ts.
env.service.provider.ts
import { EnvService } from './env.service';
export const EnvServiceFactory = () => {
// Create env
const env = new EnvService();
// Read environment variables from browser window
const browserWindow = window || {};
const browserWindowEnv = browserWindow['__env'] || {};
// Assign environment variables from browser window to env
// In the current implementation, properties from env.js overwrite defaults from the EnvService.
// If needed, a deep merge can be performed here to merge properties instead of overwriting them.
for (const key in browserWindowEnv) {
if (browserWindowEnv.hasOwnProperty(key)) {
env[key] = window['__env'][key];
}
}
return env;
};
export const EnvServiceProvider = {
provide: EnvService,
useFactory: EnvServiceFactory,
deps: [],
};
EnvServiceProvider:->It is an angular provider recipe to register EnvServiceFactory with Angular dependency injection as the factory for instantiating EnvService.
EnvServiceFactory:->It's a factory that reads environment values from window.__env and instantiates an instance of the EnvService class.
So over all summary of this env.service.provider.ts file is, we export an EnvServiceFactory function that creates an instance of the EnvService class and copies all values from the window.__env object into the EnvService instance.
Finally to register EnvServiceProvider as a recipe with Angular's dependency injection system, we must list it as a provider in our application's providers array:
app.module.ts file
import { NgModule } from '#angular/core';
import { EnvServiceProvider } from './env.service.provider';
#NgModule({
imports: [ // ... ],
providers: [EnvServiceProvider],
})
export class AppModule {}
We can now access our environment variables from anywhere in our application by injecting the EnvService, I am using it like in below.
service.ts file
import { EnvService } from '../env.service';
constructor(private _httpClinet: HttpClient, private env: EnvService) {
}
emplLoginCheckUrl = this.env.apiUrl+"/checkValidUser";
validateUserDetails(employeeDetails): Observable<any> {
console.log(this.emplLoginCheckUrl);
return this._httpClinet.post(this.emplLoginCheckUrl, employeeDetails);
}
tha's it for step 3.
step 4:->
finally what we have to do means before serving app, we have to build app with ng build --prod to get dist folder, which contains env.js file. from there we can change our URL's, if you change URL there it will automatically apply new changed URL in our application.
FOR MORE INFORMATION visit below site, thx Jurgen Van de Moere.
https://www.jvandemo.com/how-to-use-environment-variables-to-configure-your-angular-application-without-a-rebuild/
You can use ajax and if request fails, retry with other server url:
$.ajax({
type: "POST",
url: "**serverIP** ",
data: ,
success: function(){
alert("done");
},
error: function(XMLHttpRequest, errorThrown) {
alert("Here retry post with different server id ");
}
});
You could check if the request is getting failed and try making a request to another server but what if only the fourth server is working and you have to make three failed attempts all the time to reach the working one? Does not seem to be the most efficient way.
Instead, I would add an NGinx load balancer with health check:
http://nginx.org/en/docs/http/load_balancing.html

Can't use javascript File object if ionic native File defined in import.

I want to use javascript file object but can't able to use because ionic native file object already has a same key File
Look at below example:
import { File } from '#ionic-native/file';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage{
constructor(private file: File) { }
test(buf){
let file = new File([buf],'test.txt',{type:'text/plain'})
//above javascript File Object is determined as File of #ionic-native/file
}
}
Answer to my own question:
We can import with alias in typescript look below line to get ride of this.
import { File as ionicFile } from '#ionic-native/file';

Create object of javascript file in typescript

I have javascript file adal.js in Scripts folder.
I have separate Services folder into which my typescript(ts) files are there.One of my typescript file wants to use functions and variables from adal.js.
It is as follows:-
import { ConfigService } from './config.service';
import { Injectable } from '#angular/core';
//import 'expose-loader?AuthenticationContext!../../../node_modules/adal-angular/lib/adal.js';
import 'expose-loader?AuthenticationContext!../Scripts/adal.js';
let createAuthContextFn: adal.AuthenticationContextStatic = AuthenticationContext;
#Injectable()
export class AdalService {
private context: adal.AuthenticationContext;
constructor(private configService: ConfigService) {
this.context = new createAuthContextFn(configService.getAdalConfig);
}
But it is giving me error :-
Can not find namespace adal.
How can I achieve this?
EDIT 1:-
I dont have src folder I directly have typings folder as below :-
You need to add it to your global type definitions. If you're using Angular CLI, this is in the src/typings.d.ts file. You can add the following:
declare module 'adal'
Then import it as
import * as adal from '../Scripts/adal.js'

Multipart file upload and ng serve: Angular 2

I am working on the front end of a file upload service. I am currently ignoring the service path with respect to the backend. I have run into a strange problem. I have a few generated components that sit within the app component. When I end the serve from console and do ng serve again, it errors out. It says:
The only way I have found to get rid of this is to erase my uploader service injection, save the file, then re-insert the injection. This is how it is supposed to look:
The only way to get ng serve to work is to by erasing the line private service: UploaderService
Any idea why this is happening? Am I missing something with my injection? My UploaderService is marked as Injectable() and the components that use it are under Directives.
Update:
What I found out is that it is unrelated to the UploaderService. I have a component that does not inject the UploaderService. I fix it the same way I fix the other components that inject the UploaderService. By deleting the parameters of the constructor, saving, and then putting the parameters back. Then it will serve
Update2:
The generated componenet, upload.component.t, has a spec file that is generated with it, upload.component.spec.ts
It has a error that asks for parameters like so:
My UploadComponent constructor has a parameter in it, where i inject the UploaderService. In the spec.ts file, a new UploadCompent is created, but does not contain any arguments. I am guessing this is where I am going wrong. How do I work around this?
Here is my UploaderService:
import { Injectable } from '#angular/core';
import {Http, Response, HTTP_PROVIDERS, Headers, HTTP_BINDINGS, RequestOptions} from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';
import { ItemEntryComponent } from './item-entry';
import { Query } from './Query';
#Injectable()
export class UploaderService {
public URL: string;
private query: Query;
public filesSelected: Array<ItemEntryComponent> = [];
progress$: any;
progress: any;
progressObserver: any;
//CONSTRUCTOR
constructor(private http: Http) {
//***SET URL***
this.URL = 'http://localhost:7547/api/picker';
//Create Query for url
this.query = new Query(this.URL);
//Create progress attribute
this.progress$ = Observable.create(observer => {
this.progressObserver = observer
}).share();
}
}
Problem solved!
I had not realized the generated files included a spec testing file, in my example it was upload.component.spec.ts. Getting rid of those files gets rid of the errors that ask for parameters to be filled in inside the test files and now ng serve works.

Categories