I have do connection in 'Angular6' using sqlserver.
server.js
var express = require('express');
var app = express();
app.get('/', function (req, res) {
var sql = require("mssql");
// config for your database
var config = {
user: 'abc',
password: 'abc',
server: 'servername',
database: 'xyz'
};
// connect to your database
sql.connect(config, function (err) {
if (err) console.log(err);
// create Request object
var request = new sql.Request();
// query to the database and get the records
request.query('select * from tbl', function (err, recordset) {
if (err) console.log(err)
// send records as a response
res.send(recordset);
});
});
});
var server = app.listen(5000, function () {
console.log('Server is running..');
});
data.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) { }
getUsers() {
return this.http.get('https://jsonplaceholder.typicode.com/users')
}
getUser(userId) {
return this.http.get('https://jsonplaceholder.typicode.com/users/'+userId)
}
getPosts() {
return this.http.get('https://jsonplaceholder.typicode.com/posts')
}
getPhotos()
{
return this.http.get('https://jsonplaceholder.typicode.com/photos');
}
getTodos()
{
return this.http.get('https://jsonplaceholder.typicode.com/todos');
}
}
Right now I have used dummy API'S for result.
how to get my database results in service?
I have successfully get result from Sqlserver database.
I also want to display record in my Component
user.component.html
<h1>Users</h1>
Can I have to import server.js in user.component.ts.
If yes than how can I do that?
I think you are misunderstanding angular. Angular run into browser and its context is limited to that.
If you need to connect to a database, you need to use some backend technologies, like express and nodejs, as the code you posted.
The main way is to expose some backend services, like REST services, developed with a server side techonology (nodejs, j2ee, php, etc) and then use Angular to ask them for data.
Generally to achieve this goal in angular you should use HttpClient
You should search for a tutorial, like this
Angular example to request data
In angular you should create a service class to call your exposed service, then into that class you could create a method like this:
import {HttpClient, HttpHeaders} from '#angular/common/http';
import {Observable} from 'rxjs';
import {Injectable} from '#angular/core';
import {catchError, map, tap} from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class TestService {
get(): Observable<any> {
return this.http.get([YOUR_BACKEND_SERVICE_URL]).pipe(
catchError(this.handleError(`get`))
);
}
private handleError<T>(operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
console.error(error);
this.log(`${operation} failed: ${error.message}`);
return of(result as T);
};
}
}
Then you should write a component like this:
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.css']
})
export class TestComponent implements OnInit {
data: any;
constructor(private testService: TestService) { }
ngOnInit() {
this.getData();
}
getData(): void {
this.testService.get().subscribe(data => console.log(data));
}
}
You need to create service and component with AngularCli in order to avoid to manually declare and import them into app.module.ts
For a better understanding of what is happening I suggest you to read Angular Tour of Heroes tutorial, Services section
Related
I created a Node.js application and also an Angular application. I need to get data from the database and also store data to the database. I'm having problems connecting my Express.js server to the Angular application.
File user.service.ts
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs';
import { User } from '../User';
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { BASE_URL } from '../const/config';
import { MONGO_EXPRESS_URL } from '../const/config';
#Injectable({
providedIn: 'root',
})
export class UserService {
constructor(private http: HttpClient) {}
getUsers(): Observable<User[]> {
return this.http.get<User[]>(`${MONGO_EXPRESS_URL}/fetchdata`);
}
}
File users.component.ts
import { Component, OnInit } from '#angular/core';
import { UserService } from 'src/app/services/user.service';
import { User } from '../../User';
#Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.css'],
})
export class UsersComponent implements OnInit {
users: User[] = [];
constructor(private userService: UserService) {}
ngOnInit(): void {
this.userService.getUsers().subscribe((users) => (this.users = users));
}
}
This error pops up when I run the Angular application:
File server.js
app.use("/", router);
app.listen(port, function () {
console.log("Server is running on Port: " + port);
});
router.route("/fetchdata").get(function (req, res) {
users.find({}, function (err, result) {
if (err) {
res.send(err);
} else {
res.send(result);
}
});
});
The problem is the route: https://localhost:4000.
It would be http://localhost:4000 (http:// instead of https://).
It should kind of look like this on your Node.js. You should set up the Express.js server like so:
constructor() {
this.app = express()
}
Initialize{
this.app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
res.header('Access-Control-Allow-Methods', 'OPTIONS, GET, POST, PUT');
if('OPTIONS' === req.method){
res.sendStatus(200);
}
else {
next();
}
})
this.app.use(RouterWebservices)
this.app.listen(your.HttpPort, your.Ip, () => {
console.log('Server now listening at ', your.HttpPort, 'IP ', your.Ip);
})
}
Then you need to declare your variables in a router.webservice.ts file:
export const RouterWebservices = express.Router()
RouterWebservices.get('/fetchdata', FetchWebservice)
And write a FetchWebserivce where you simply answer the request with data.
I want to call a Rest-Service (Spring MVC) to receive a list of releases. On client side (AngularJs) I use a service creating a HttpClient call. I also have a registered HttpInterceptor to use simple Basic Authentification. The interceptor is provided in app.modules.ts and is called during the rest call.
Unfortunately I get statuscode 401 and I cannot find the 'Authentification' entry in the header. What is missing?
Interceptor:
import { Injectable } from '#angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '#angular/common/http';
import { Observable } from 'rxjs';
#Injectable()
export class BasicAuthInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = request.clone({
setHeaders: {
Authorization: `Basic username:password`
},
});
return next.handle(request);
}
}
Service class:
import { Injectable } from '#angular/core';
import { Observable, of } from 'rxjs/';
import { HttpClient } from '#angular/common/http';
import { catchError, map, tap } from 'rxjs/operators';
import { Release } from './Release';
#Injectable()
export class ReleasesService {
constructor(
private http: HttpClient) {}
private releasesUrl = 'http://localhost:8080/releases/showAll';
getReleases(): Observable<Release[]> {
return this.http
.get<Release[]>(this.releasesUrl)
.pipe( tap(releases => this.log('fetched releases')),
catchError(this.handleError('getReleases', [])));
}
private handleError<T> (operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
console.error(error); // log to console instead
return of(result as T);
};
}
private log(message: string) {
console.info(message);
}
}
app.modules.ts
providers: [
APP_PROVIDERS,
{ provide: HTTP_INTERCEPTORS, useClass: BasicAuthInterceptor, multi: true },
],
I found the solution.
Setting the header was correct. But I had to add following parameter to the HttpClient-call: { withCredentials: true }
getReleases(): Observable<Release[]> {
return this.http
.get<Release[]>(this.releasesUrl, { withCredentials: true })
.pipe( tap(releases => this.log('fetched releases')),
catchError(this.handleError('getReleases', [])));
}
Then the credentials are passed to the server.
In my quest to learn the MEAN stack i'm building a small multi tenanted app and struggling with getting my users / tenants all signed up. Backend is sorted I believe just cant quite figure out how to get angular to play ball.
Flow... User signs up a new account, Which concurrently creates a new tenant. Like so...
var express = require('express');
var router = express.Router();
var bcrypt = require('bcryptjs');
var Tenant = require('../models/tenant');
var User = require('../models/user');
router.post('/', function (req, res, next) {
var tenant = new Tenant({
name: req.body.name
});
tenant.save(function(err, tenant) {
Tenant.findById(tenant._id, function(err, tenant) {
var user = new User({
first_name: req.body.first_name,
last_name: req.body.last_name,
email: req.body.email,
password: bcrypt.hashSync(req.body.password, 10),
active: req.body.active,
tenant: tenant
})
user.save(function (err, user) {
if (err) {
return res.status(500).json({
title: 'An error has occured',
error: err
});
}
res.status(201).json({
message: 'User created',
obj: user
});
})
});
});
// tenant.findByIdAndUpdate(tenant._id, {owner: user._id});
});
module.exports = router;
This, for the most part, works as intended. At least in testing with postman.
In angular my signup component (in its working state before I tried introducing tenants) looks like:
import { Component, OnInit } from '#angular/core';
import {FormControl, FormGroup, Validators} from "#angular/forms";
import {Router} from "#angular/router";
import {AuthService} from "../auth.service";
import {User} from "../user.model";
import {Tenant} from "../tenant.model";
#Component({
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.css']
})
export class SignupComponent implements OnInit{
myForm: FormGroup;
constructor(private router: Router, private authService: AuthService) {}
onSubmit() {
const user = new User(
this.myForm.value.first_name,
this.myForm.value.last_name,
this.myForm.value.email,
this.myForm.value.password
);
this.authService.signup(user)
.subscribe(
data => console.log(data),
error => console.error(error)
);
this.router.navigate(['/signup/success/' + this.myForm.value.email]);
}
ngOnInit() {
this.myForm = new FormGroup({
coName: new FormControl('', Validators.required),
email: new FormControl('', Validators.required),
password: new FormControl('', Validators.required),
active: new FormControl(true, Validators.required)
});
}
}
and my AuthService (again in its working state before i tried introducing tenants) ...
import { Injectable } from "#angular/core";
import { Http, Headers, Response } from "#angular/http";
import 'rxjs/Rx';
import { Observable } from "rxjs";
import { User } from "./user.model";
import { Tenant } from "./tenant.model";
#Injectable()
export class AuthService {
constructor(private http: Http) {}
signup(user: User) {
const body = JSON.stringify(user);
const headers = new Headers({'Content-Type': 'application/json'});
return this.http.post('/api/tenant', body, {headers: headers})
.map((response: Response) => response.json())
.catch((error: Response) => Observable.throw(error.json()));
}
signin(user: User) {
const body = JSON.stringify(user);
const headers = new Headers({'Content-Type': 'application/json'});
return this.http.post('/api/user/signin', body, {headers: headers})
.map((response: Response) => response.json())
.catch((error: Response) => Observable.throw(error.json()));
}
logout() {
localStorage.clear();
}
isLoggedIn() {
return localStorage.getItem('token') !== null;
}
}
Now, i'm not looking for a handout, or anyone to write this for me... just a friendly nudge in the right direction, if that's allowed on here ;) . Would it be easier to just abandon the reactive form and use ngModel? Or perhaps, define a new angular model that is a hybrid of user/tenant?
Cheers.
In case anyone sees this and cares... I was putting a level of importance on my angular models mimicking my mongoose models. I ended up creating a new angular model (signup.model.ts) made up of the relevant fields from both my tenant and user mongoose models. Now I'm not sure this was necessarily the ideal way to structure this, however it works so feel I can put it in as an answer.
Cheers.
I'm fairly new to AngularJS (2.0.0-beta.16). I've managed to setup a service that pulls data from an API, via a GET request. Now, how do I set it up to run the GET request every n seconds? I've seen other posts saying you could just using this._http.get(...).interval(5000).map(...);, however when I've tried that, I get a Typescript compilation error:
Property 'interval' does not exist on type 'Observable'.
Am I making a silly mistake or is there a better pattern for doing this?
import { Injectable } from 'angular2/core';
import { Http, Response } from "angular2/http";
import { Observable } from "rxjs/Observable";
import * as _ from "js/lodash.js";
import { Foo } from "./foo";
#Injectable()
export class FooService {
fooList: Observable<Foo[]>;
constructor(private _http: Http) {
this.fooList = this._http.get('http://localhost:9090/api/').map(
response => {
var json = response.json();
if(response.ok === true) {
let newFooList: Foo[] = [];
_.forEach(json, f => {
newFooList.push(new Foo(f));
});
return newFooList;
}
throw Error("Bad status: " + response);
});
}
}
This is probably not the only (or the best) way, but it worked for me. The only issue is that the first GET request is delayed by the amount of time specified by create().
import { Injectable } from "angular2/core";
import { Http, Response } from "angular2/http";
import { Observable } from "rxjs/Observable";
import { IntervalObservable } from "rxjs/observable/IntervalObservable";
import * as _ from "js/lodash.js";
import { API_URI } from "./constants";
import { Foo } from "./foo";
#Injectable()
export class FooService {
public fooList: Observable<Foo[]>;
constructor(private _http: Http) {
this.fooList = IntervalObservable.create(2000).flatMap(
() => {
return this._http.get(API_URI);
}).map(
response => {
var json = response.json();
if(response.ok === true) {
let newFooList: Foo[] = [];
_.forEach(json, f => {
newFooList.push(new Foo(f));
});
return newFooList;
}
throw Error("Bad status: " + response);
});
}
}
I have the following code for my service
import {Injectable} from 'angular2/core';
import {Http} from 'angular2/http';
import {Response} from "angular2/http";
import {PRIVATE_SERVERS} from "../mock/private_servers_list";
import 'rxjs/Rx';
/*import {PRIVATE_SERVERS} from "../mock/private_servers_list";*/
#Injectable()
export class PrivateServerService {
http= null;
PRIVATE_SERVERS = null;
constructor(http:Http){
this.http = http;
}
logError(err){
console.log("some error");
}
getPrivateServers(){
this.http.get('http://private-server.eviry.com/get_private_servers')
.map(res => res.json())
.subscribe(
data => this.PRIVATE_SERVERS = data, //printing data here gives me the correct value
err => this.logError(err),
() => console.log('Private Server fetching complete')
);
console.log(this.PRIVATE_SERVERS);
return this.PRIVATE_SERVERS;
}
}
I have injected this service in to a component called private-server.component. Basically, in this service I am trying to get a list of private servers using the url http://private-server.eviry.com/get_private_servers
I access this url in getPrivateServers() function. When I print the response within the subscribe method, I can see the data fetched correctly.
However, when I try to console.log(this.PRIVATE_SERVERS), it prints null. Is this the correct way to use the angular service or is there a way to make it wait for the response?
The assignment happens in an asynchronous callback. If you want to use its value outside that callback, you need to wait for it to complete.
You can also use Event Emitter to react asynchronous to the response.
Here is an good introduction to Observables in Angular2.
PrivateServerService.ts
import { Injectable } from 'angular2/core';
import { Http } from 'angular2/http';
import { Response } from "angular2/http";
import { PRIVATE_SERVERS } from "../mock/private_servers_list";
import 'rxjs/Rx';
/*import {PRIVATE_SERVERS} from "../mock/private_servers_list";*/
#Injectable()
export class PrivateServerService {
PRIVATE_SERVERS = null;
constructor(private http: Http) {
this.setPrivateServerMocksData();
}
logError(err) {
console.log("some error");
}
getPrivateServers() {
return this.http.get('http://private-server.eviry.com/get_private_servers')
.map(res => res.json());
}
setPrivateServerMocksData() {
this.getPrivateServers()
.subscribe((data) => {
this.PRIVATE_SERVERS = data
console.log(this.PRIVATE_SERVERS);
},
(err) => {
this.logError(err)
});
}
}
YourComponent.ts
getPrivateServerInfo() {
this.privateServerService.getPrivateServers()
.subscribe((data) => {
//you have your data here to work with
console.log(data);
},
(err) => {
this.logError(err)
});
}