Implement properly list of Objects from rest api - spring

I want to implement Angular example which gets list from rest API. I tried this:
SQL query:
#Override
public Iterable<Merchants> findAll() {
String hql = "select e from " + Merchants.class.getName() + " e";
TypedQuery<Merchants> query = entityManager.createQuery(hql, Merchants.class);
List<Merchants> merchants = query.getResultList();
return merchants;
}
Rest controller:
#RestController
#RequestMapping("/merchants")
public class MerchantController {
#GetMapping("/list")
public Iterable<Merchants> getMerchantsList() {
return merchantRepository
.findAll();
}
}
Service:
#Injectable({
providedIn: 'root'
})
export class MerchantService {
constructor(private http: HttpClient) {
}
getList() {
return this.http.get("...../api/merchants/list");
}
}
Component:
#Component({
selector: 'app-terminal',
templateUrl: './terminal.component.html',
styleUrls: ['./terminal.component.scss']
})
export class TerminalComponent implements OnInit {
merchants: Merchant[];
constructor(private merchantService: MerchantService,
private router: Router,
private route: ActivatedRoute) {
}
ngOnInit() {
this.merchantService.getList();
}
}
But when I lock the component via web page nothing happens. Can you give me some advice where I'm wrong?
Probably my typescript is somewhere incorrect?

You need to call subscribe on the Observable, otherwise it won't make the HTTP request
ngOnInit() {
this.merchantService.getList().subscribe(res => {
console.log("The response is", res);
});
}

Related

NgRx Data, EntityCollectionService's default Api not Match Asp.net Core Web Api

I have service that extends EntityCollectionServiceBase of ngrx\data
#Injectable()
export class ProductService extends EntityCollectionServiceBase<Product> {
constructor(elementsFactory: EntityCollectionServiceElementsFactory) {
super('Product', elementsFactory);
}
and my asp.net controller is like this
[Route("api/[controller]")]
[ApiController]
public class ProductController : ApiController
{
// GET: api/<ProductController>
[HttpGet]
public async Task<ActionResult<ProductsListVm>> GetAll()
{
var vm = await Mediator.Send(new GetProductsListQuery());
return Ok(vm);
}
// GET api/<ProductController>/5
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
}
so when I call GetAll on entity service of ngrx\data it requests {url}/api/products/ while the asp.net web API controller only responds to {url}/api/product/
any configuration or trick to resolve with minimal code
You should define a plural name as follwoing:
import { EntityMetadataMap } from 'ngrx-data';
const entityMetadata: EntityMetadataMap = {
Product: {},
};
const pluralNames = { Product: 'product' };
export const entityConfig = {
entityMetadata,
pluralNames
};

axios can't accept response data sent by Spring Boot controller

I tried to integrate vue.js with Spring Boot. This is my vue.js code:
<template>
// ...
</template>
<script>
export default {
name: "Login",
data: function() {
return {
username: '',
password: '',
msg: ''
}
},
methods: {
// post data to Spring Boot
login() {
axios.post('/login',{
username: this.username,
password: this.password
})
.then(function(response) {
if(response.data.code === 200){
this.$store.dispatch('setCurrentUser',this.username);
// vue-route
this.$router.push('/course');
} else {
this.msg = response.message;
}
})
.catch(function(err) {
this.msg = 'error';
});
}
}
};
</script>
And this is my Spring Boot controller:
#RestController
#ResponseBody
public class LoginController {
#Autowired
private ResultGenerator resultGenerator;
#PostMapping("/login")
public RestResult login(String username, String password){
if(username.equals("123") && password.equals("123")){
return resultGenerator.getSuccessResult();
} else {
return resultGenerator.getFailResult("error");
}
}
}
The controller will return JSON data which looks like:{"code":200,"message":"success","data":null}. When the login method was called, controller could accept the username and password and controller sent response data too. But that was all and vue-router didn't work. All I saw in the brower was:
Can anyone help?
------------------ Addition -----------------------
This is vue-router config:
const routes = [
{
path: '/',
component: Login
},
{
path: '/signin',
component: Signin
},
{
path: '/course',
component: Course
}
];
const router = new VueRouter({
routes,
mode: "history"
});
The problem could be that you return resultGenerator.getSuccessResult(). Have you tried redirecting to the '/course' path inside Spring Boot Controller?
#PostMapping("/login")
public RestResult login(String username, String password){
if(username.equals("123") && password.equals("123")){
this.$router.push('/course');
} else {
return resultGenerator.getFailResult("error");
}
}
If the Vue.js and Spring boot are 2 different apps (like backend and frontend), this may help:
Try using #CrossOrigin (CORS) on your #controller or on the method that expose the rest, I had similar issues on an Ionic 3 proyect and thaty solved the problem.
EXAMPLE:
#CrossOrigin(origins = "http://localhost:9000")
#GetMapping("/greeting")
public Greeting greeting(#RequestParam(required=false, defaultValue="World") String name) {
System.out.println("==== in greeting ====");
return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
It should look something like this:
#RestController
#ResponseBody
public class LoginController {
#Autowired
private ResultGenerator resultGenerator;
#CrossOrigin(origins = "http://localhost:9000") // The IP:PORT of the vue app origin
#PostMapping("/login")
public RestResult login(String username, String password){
if(username.equals("123") && password.equals("123")){
return resultGenerator.getSuccessResult();
} else {
return resultGenerator.getFailResult("error");
}
}
}
Source from spring.io Here! :D

How to use Angular Observable

I have got problem with getting user information using http request to my rest api server, I don't know what is wrong....
When user click on login button, Angular send request to server with username and password, if is correct it returns user info else it returns null. Problem is that variable user in user service is still null though the username and password are correct.
I don't know how to solve this problem, so if you help me I will be happy ! Thank for any help.
REST API:
package cz.flay.fellcms.http;
import cz.flay.fellcms.dao.UsersRepository;
import cz.flay.fellcms.entities.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
#CrossOrigin
#RestController
#RequestMapping(path = "/api/users")
public class UsersRestController {
#Autowired
private UsersRepository usersRepository;
Logger logger = LoggerFactory.getLogger(UsersRestController.class);
#CrossOrigin
#GetMapping(path = "/all")
public #ResponseBody Iterable<User> getAll(){
return usersRepository.findAll();
}
#CrossOrigin
#GetMapping(path = "/verify", params = {"username", "password"})
public #ResponseBody User verify(#RequestParam(value = "username") String username, #RequestParam(value = "password") String password){
logger.info("t");
return usersRepository.verify(username, password);
}
}
User Service
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { User } from '../entities/User';
#Injectable()
export class UserService {
private usersUrl: 'http://localhost:8080/api/users';
user: User;
verifyUrl: string;
constructor(private http: HttpClient) {}
isLoggedIn() {
return this.user != null;
}
isAdmin() {
return this.user.isAdmin;
}
unLoggin() {
this.user = null;
}
login(username: string, password: string) {
this.verifyUrl = 'http://localhost:8080/api/users/verify?username=' + username + '&password=' + password;
this.http.get<User>(this.verifyUrl).subscribe(data => this.user = data);
if (this.user != null) {
return true;
} else {
return false;
}
}
}
You're calling if (this.user !== null) too soon. That evaluation will get called before the request goes away and back. Try this:
login(username: string, password: string) {
this.verifyUrl = `http://localhost:8080/api/users/verify?username=${username}&password=${password}`;
return this.http.get<User>(this.verifyUrl)
.map(data => {
this.user = data
if (this.user != null) {
return true;
} else {
return false;
}
});
}
The thing is though, wherever you call this login method, it's now an observable you have to subscribe to, not a sync method.

Cannot read property ‘children’ of undefined ionic

I am getting an error while trying to read a json. I am using asp.net web api.
My code looks like this:
export class ProdutoListaPage {
public produto: Array<string>;
private url: string = "http://localhost:50907/api/consulta/BuscaProduto";
constructor(public navCtrl: NavController, public navParams: NavParams, public http:Http) {
this.http.get(this.url).map(res => res.json())
.subscribe(data => {
this.produto = data.data.children;
});
}
ionViewDidLoad() {
console.log('ionViewDidLoad ProdutoListaPage');
}
}
If your api response is this : the correct way to assign the produto array is this : this.produto = data;

MVC in Angular 2 - update component from service?

AIM: I send a http request from angular 2 ui to java server. While it is executing, server generates messages with progress status so I can update progress bar on ui.
I have 3 entities: AppComponent, AppService and WebsocketService.
Here is a simplified example of WebsocketService. It can subscribe to message topic and perform some actions on incoming each message.
export class WebsocketService {
private client: Client;
constructor() {
var service = this;
service.client = Stomp.client('ws://localhost:8080/stomp/websocket');
service.client.connect("user", "pass", function () {
service.client.subscribe("/progress", function (message) {
// some actions here
})
});
}
}
So, my question is: how to update AppComponent's property (field) value, which is binded to template, from AppService or even WebsocketService? Use a setter? Is it allright from the terms of MVC?
There is more than one way to do this but I would use a "Subject" stream.
Here is an example:
import {Injectable} from '#angular/core';
import {Http, Headers, RequestOptions, Response} from '#angular/http';
import {Observable} from 'rxjs/Rx';
import {Subject} from 'rxjs/Subject';
import {NextObserver} from 'rxjs/Observer';
export class WebsocketService {
public ProcessingMessages$: Observable<string>;
private client: Client;
private processingMessages: Subject<string>;
constructor() {
this.processingMessages = new Subject<string>();
this.ProcessingMessages$ = this.processingMessages.asObservable();
var service = this;
service.client = Stomp.client('ws://localhost:8080/stomp/websocket');
service.client.connect("user", "pass", function () {
service.client.subscribe("/progress", function (message) {
this.processingMessages.next(message);
})
});
}
}
// Sample Component
#Component({
selector: 'my-component',
template: 'WebsocketService Message: {{Message}}',
})
export class Sample Component implements OnInit {
public Message: string;
constructor(
private service: WebsocketService
) {
}
ngOnInit() {
this.service.ProcessingMessages$.subscribe((message: string) => {
this.Message = message;
});
}
}

Resources