I have built an app using ionic but my clients will be using different servers for accessing API. How can I give an option to set the base url by the user to call the desired server API?
There are 2 ways:
The temporary way:
This way, when the app is closed, it reset to the default api:
create a service ionic generate service
in this service, make a variable that will have the url you need
make some getter and setter
import this service where you need it (were you change your api, and in your api service)
The permanent way:
Use the file plugin to make, for example, a JSON that you will read/write with the api url in it.
set your base url in environment.ts file and use in any of service
export const environment = {
production: false,
baseUrl: 'http://localhost:3000/'
};
auth.service.ts
import { Injectable } from '#angular/core';
import { Observable} from 'rxjs';
import { HttpClient } from '#angular/common/http';
import { environment } from '../../../environments/environment';
#Injectable({
providedIn: 'root'
})
export class AuthService {
baseUrl = environment.baseUrl;
constructor(
private http: HttpClient
) { }
Userlogin(data: any): Observable<any> {
return this.http.post(this.baseUrl + 'user/login', data);
}
}
Related
I want to record the frequency of accessing the API. I want to insert every API access directly into the database through middleware. I don't know how to access the database in nestjs middleware.
The code will like:
import { NestMiddleware, Injectable } from '#nestjs/common';
import { Request, Response } from 'express';
// console.log('StatisticsMiddleware');
#Injectable()
export class StatisticsMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: Function) {
// console.log(req.originalUrl, req.ip, req.connection.remoteAddress);
const url = req.originalUrl
const ip = req.ip || req.connection.remoteAddress
//
Db.insert('LOG_TABLE', url, ip)
next();
}
}
A middleware class is just like any other #Injectable() class in NestJS, and as such can have the database injected into it. The docs mention you can use injection like any other provider, so all you'll need to do is provide your database connection (be it a Mongo Model, a TypeORM Repository, or anything else) and you'll be good to access from there.
I'm currently working on a project using Aurelia as the front-end framework, and I'm wondering if there's a more eloquent and less redundant way to set the request header in my API services. The following is an example.
In this Post service, I have created a configureHeaders method that I'm calling prior to every API call because, otherwise, I run into the case where the web token has changed but the request header isn't updated. While creating this configureHeaders method is a functional workaround, I have to do it for each of my services, and it's feeling very redundant.
Is there a way to configure the request header application-wide so that I don't have to create a configureHeaders method for each service and call it for each request?
import {inject} from 'aurelia-framework';
import {HttpClient} from 'aurelia-http-client';
import environment from 'environment';
#inject(HttpClient)
export class Post {
constructor(http) {
this.http = http;
}
configureHeaders() {
this.token = window.localStorage.getItem('token') || null;
this.http = this.http
.configure(x => {
x.withBaseUrl(environment.serverBaseURL);
x.withHeader('Authorization', `Bearer ${this.token}`);
});
}
getPosts() {
this.configureHeaders();
return this.http.get('post')
.then(posts => {
return JSON.parse(posts.response);
});
}
}
As R.Richards commented, Aurelia's HttpClient Interceptor is what you're after.
Here's a class example - as opposed to object with anonymous functions
1.) Declare the interceptor
import {Interceptor, HttpResponseMessage, RequestMessage} from 'aurelia-http-client'
export class CustomInterceptor implements Interceptor {
request(request: RequestMessage): RequestMessage {
//Do request interceptor here
return request;
}
response(response: HttpResponseMessage): HttpResponseMessage{
//Do response interception here
return response;
}
}
2.) Register the interceptor as part of your default http client within your main.js
import {CustomInterceptor} from 'path/to/custom-interceptor'
...
...
http.configure(config => {
//config stuff here
).withInterceptor(new CustomInterceptor())
This should suit your eloquence!
I have an API class that has various methods that communicate to a backend like "login, register, createPost" etc. I am connecting this class to a reducer. The reducer contains the state of the user info, which I want to be accessible in my Api class:
import axios from 'axios';
import React, { Component } from 'react';
import { connect } from 'react-redux';
#connect(state => ({
api: state.api,
}) )
export default class Api extends Component {
export const login = async({args}) => {
const url = this.props.api.url.concat('/login/');
const config = {
headers: {
'X-CSRFTOKEN': this.props.api.token
}
};
try {
const data = await axios.post(url, {"username": args.username, "password": args.password}, config);
this.props.api.key = data.data.token;
this.props.api.user = data.data.user;
return data;
} catch (e) {
throw e;
}
}
};
async createPost(args (content of the post)) {
try {
const url = this.props.api.url.concat('/post/PostList');
const Response = await axios.post(url, {...args}, !**this.props.api.key**! );
return Response;
} catch (e) {
throw e;
}
}
In the first method, I set the imported state.key and state.user (connected via redux) information, and I want to access that in the second method (this.props.api.key I surrounded by stars). I am trying to do it this way because I have a multitude of actions on different screens, and users have to pass their authentication information to the api method they're calling on top of whatever they're trying to do in order to be able to execute whatever respective action. I figure that it's easier to pass the user info in my Api class instead of importing the Api state into every different file I call the actions in.
The issue I'm running into is I can't instantiate a new object of api like
const api = new Api();
Because it gives me an error "cannot read property store of undefined," so I can't call the actions api.login(withArgs) in respective files, and if I make the methods static they won't have access to this.props.whatever
How do I instantiate a class that's connected to the global state of redux, or how can I access the info in that global state outside of my reducer file?
Since Api extends React.Component, why are you trying to instantiate the class yourself vs. letting React render it for you?
ReactDOM.render(<Api store={store} />)
or if you are not using JSX
ReactDOM.render(React.createElement(Api, { store })
I'm setting up aurelia-auth and configured endpoints for my authorization server and a protected api:
aurelia.use.plugin('aurelia-api', configure => {
configure
.registerEndpoint('auth', 'http://localhost:5000/')
.registerEndpoint('api', 'http://localhost:5006')}
When I want to fetch data I inject the AuthService into my module and then call
this.authService.config.client.client.fetch('StaticData/offices')
but this calls against the auth endpoint not the api one, how do I tell the fetch client to use the non-default endpoint?
I was heading down the wrong path, you use the configuration object off aurelia-api to get an endpoint you can then call:
import { inject } from 'aurelia-framework';
import { Config } from 'aurelia-api'
#inject (Config)
export class Locations {
constructor (private apiEndpointConfig: Config)
{}
dataItems;
hasItems: boolean;
created(){
var api = this.apiEndpointConfig.getEndpoint('api');
api.client.fetch('StaticData/offices')
.then(response=>response.json())
.then(response=>
{
this.dataItems=response;
this.hasItems=true;
});
}
}
I'm writing an angular2 dart application using Intellij.
I created a provider called Auth that should be injected to the app component.
I defined the Auth service using the following code:
import 'package:angular2/core.dart';
import 'package:auth0_lock/auth0_lock.dart';
import './config.dart';
#Injectable()
class Auth {
Auth0Lock lock;
Auth() {
this.lock = new Auth0Lock(configObj.auth0.apiKey, configObj.auth0.domain);
}
updateProfileName(data) {
var profile = data['profile'] != null ? data['profile'] : data;
print(profile['name']);
}
login() {
this.lock.show(popupMode: true, options: {'authParams': {'scope': 'openid profile'}}).then(this.updateProfileName);
}
}
and the app component using the following code:
import 'package:angular2/core.dart';
import 'package:angular2/router.dart';
import 'welcome_component.dart';
import 'auth_service.dart';
#Component(
selector: 'my-app',
templateUrl: '/www/my-app.html',
providers: [Auth]
)
#RouteConfig(const [
const Route(path: '/welcome', component: WelcomeComponent, name: 'welcome')
])
class AppComponent {
Auth auth;
AppComponent(Auth auth) {
this.auth=auth;
}
}
now intellij is complaning about the providers array with the error message arguments of constant creation must be constant expressions.
I'm new to dart... but if the Component configuration needs consts, how can I provide classes to be used there ?
thanks
Just adding const should do:
providers: const [Auth]
The error you're seeing is because [Auth] creates a List that — although it contains only a const memeber — is itself not constant. (For example, it could be added to, or cleared.) Dart requires you to specify explicitly that the List is constant.