Getting data from PHP using ionic2 - php

loginstatus.php
$data = (object)['login'=>'yes'];
echo json_encode($data);
app.component.ts
import { Component } from '#angular/core';
import { Platform } from 'ionic-angular';
import { StatusBar } from '#ionic-native/status-bar';
import { SplashScreen } from '#ionic-native/splash-screen';
import { PostsService } from './services/posts.service';
import { HomePage } from '../pages/home/home';
#Component({
templateUrl: 'app.html',
providers: [PostsService]
})
export class MyApp {
rootPage:any = HomePage;
constructor(public postsService: PostsService, platform: Platform, statusBar: StatusBar, splashScreen: SplashScreen) {
platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
statusBar.styleDefault();
splashScreen.hide();
});
}
ngOnInit(){
console.log("initialized");
this.postsService.loginstatus().subscribe(status =>{
console.log(status);
alert(status);
});
}
}
services/posts.service.ts
import {Injectable} from '#angular/core';
import {Http} from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class PostsService{
constructor(private http: Http){
}
loginstatus(){
console.log('called00');
return this.http.get('http://localhost/sugumar/mysuite/logintest.php')
//return this.http.get('https://jsonplaceholder.typicode.com/posts');
.map(res => res.json());
}
}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { ErrorHandler, NgModule } from '#angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '#ionic-native/splash-screen';
import { StatusBar } from '#ionic-native/status-bar';
import {HttpModule} from '#angular/http';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
#NgModule({
declarations: [
MyApp,
HomePage
],
imports: [
BrowserModule,
HttpModule,
IonicModule.forRoot(MyApp)
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
HomePage
],
providers: [
StatusBar,
SplashScreen,
{provide: ErrorHandler, useClass: IonicErrorHandler}
]
})
export class AppModule {}
if request data from
https://jsonplaceholder.typicode.com/posts
It alerts the data correctly. If I request data from my local server
loginstatus.php
It doesn't log and it doesn't alert.

Related

how to use react-query with a Laravel api

I am following a example that uses react-query, the example works fine with the test data, but when it hits a backend that I am building is not working as expected, I mean, it retrieves the information, but don't cache the information, always hits the server, but using the example, that was not happening.
hooks/user.js
import { useQuery } from "react-query";
import axios from "axios";
export const useUsers = (activePage) => {
return useQuery(
// Add activePage as a dependency
["users", activePage],
async () => {
const { data } = await axios.get(
//works fine here
`https://reqres.in/api/users?page=${activePage}`
//Here not works properly
//`http://127.0.0.1:8000/api/users?page=${activePage}`
);
return data;
},
// This tells React-Query that this is Query is part of
// a paginated component
{ keepPreviousData: true }
);
};
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { QueryClient, QueryClientProvider } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";
const queryClient = new QueryClient(); // Global Store Instance
ReactDOM.render(
<QueryClientProvider client={queryClient}>
<React.StrictMode>
<App />
</React.StrictMode>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>,
document.getElementById('root')
);
reportWebVitals();
App.js
import { useState } from "react";
import TableHeader from "./components/tableHeader/TableHeader";
import TableRow from "./components/tableRow/TableRow";
import Pagination from "./components/pagination/Pagination";
// Import the hook
import { useUsers } from "./hooks/users";
const App = () => {
const [activePage, setActivePage] = useState(1);
// React Query takes care of calling
// userUsers hook when App.js is rendered.
const usersList = useUsers(activePage);
return (
<>
<TableHeader />
{/* map through users list */}
{usersList.data &&
usersList.data.data.map((user) => <TableRow user={user} key={user.id} />)}
<Pagination
activePage={activePage}
setActivePage={setActivePage}
pages={2}
/>
</>
);
};
export default App;
In the example, when I hit the api again, I mean, I go to other page twice, in the network tab is says this: (disk cache)
Which is the expected behaviour, but when it is using my laravel api, then is not working properly, it is able to retrieve the information, but always hits the server, not the cache
In my laravel app I have this:
routes/api.php
Route::get('/users', [UsersController::class, 'index']);
UsersController.php
...
public function index()
{
return User::paginate(10);
}
...
The frontend is using this url:
http://localhost:3000/
and the backend is using this:
http://localhost:8000/
maybe is because of the port? but using the external api: https://reqres.in/api/users?page=1 it works without problem, it uses the cache as expected, do weird. I think I need to modify my api
This is the response of my local api:
{
"current_page":1,
"data":[
{
"id":1,
"first_name":"sergio",
"avatar_url":"https:\/\/url",
"age":30,
"created_at":"2022-09-11T22:29:52.000000Z",
"updated_at":"2022-09-11T22:29:52.000000Z"
},
{
"id":2,
"first_name":"jhon",
"avatar_url":"https:\/\/url",
"age":39,
"created_at":"2022-09-11T22:30:03.000000Z",
"updated_at":"2022-09-11T22:30:03.000000Z"
},
...
...
],
"first_page_url":"http:\/\/127.0.0.1:8000\/api\/users?page=1",
"from":1,
"last_page":9,
"last_page_url":"http:\/\/127.0.0.1:8000\/api\/users?page=9",
"next_page_url":"http:\/\/127.0.0.1:8000\/api\/users?page=2",
"path":"http:\/\/127.0.0.1:8000\/api\/users",
"per_page":3,
"prev_page_url":null,
"to":3,
"total":25
}
What can I do? thanks.
Replace return in your controller by this one
return response()->json(User::paginate(10));

Call service from outside app

I have 2 different apps, one is based on Angular2 and the other with PHP.
I need to call a service's function of the first one (Angular) from the second one (PHP). Is it possible even if it is weird and ugly?
I know how to call a PHP file inside an Angular app, but not the other way.
Here are my test files:
webService.component.ts
import { Component } from '#angular/core';
import {Observable} from "rxjs/Observable";
import {ActivatedRoute, Params} from "#angular/router";
import {WebService} from "./webService.service";
#Component({
selector: 'webService-element',
template: `{{result}}`
})
export class WebServiceComponent {
webService: WebService;
result: any;
constructor(private route: ActivatedRoute, webService: WebService) {
this.webService = webService;
}
ngOnInit() {
this.route.params.subscribe((params: Params) => {
let aId = params['aId'];
let bId = params['bId'];
this.getPif(aId, bId);
});
}
getPif(aId: any, bId: any): any {
this.result = this.webService.getPif();
return this.webService.getPif();
}
}
webService.service.ts
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import { Observable } from 'rxjs/Rx';
#Injectable()
export class WebService {
constructor(private http: Http) {}
//getPif(): Observable<any> {
getPif(): any {
console.log("rraaahhhhh");
return "pif";
}
}
webService.routing.ts
import { Routes, RouterModule } from "#angular/router";
import {WebServiceComponent} from "./webService.component";
const WEBSERVICE_ROUTES: Routes = [
{ path: '', component: WebServiceComponent },
{ path: 'getTest/:aId/:bId', component: WebServiceComponent },
];
export const webServiceRouting = RouterModule.forChild(WEBSERVICE_ROUTES);
webService.module.ts
import { NgModule } from "#angular/core";
import {WebService} from "./webService.service";
import {WebServiceComponent} from "./webService.component";
import {webServiceRouting} from "./webService.routing";
#NgModule({
imports: [
webServiceRouting
],
declarations: [
WebServiceComponent
],
providers: [
WebService
]
})
export class WebServiceModule { }
I tried to launch "http://localhost:3000/webService/getTest/1/2"
Thanks a lot for your help!

Angular: JSON html markup with angular component dynamic

EDIT 1:
Thank you for #Narm for the solution. I got it working!
In let myTemplate = '<div class="test" (tap)="test();">Test</div>';, I have a tap function.
When I click on it to invoke the function, it does not work and gives an error:
ERROR TypeError: _co.another_test is not a function
Here is what I have so far:
ngOnInit(){
...
let myTemplate = `<div class="test" (tap)="test();">Test</div>`;
...
}
test(){
console.log("Test");
}
Any thoughts?
Original Question Below
From php using REST, I am getting html markup with Angular components:
From php:
function send_html(){
$html = '<div class="test" *ngIf="data">This is an example</div>';
return $html;
};
Then in my angular project, I am trying to add this html dynamically using componentFactoryResolver: (I understand that it only accepts Angular component)
Here is my though process:
In main.ts (shown below): call the getDynamicREST() and get the $html from php.
When the data is fetched, then send this to my_component.ts to make this as an Angular component.
Once the html markup becomes a part of Angular component, then use createComponent to create the component.
Of course, it doesn't work...
This is what I have so far: Please feel free to tear it apart.
main.html
<div class="top">
<ng-template #main></ng-template>
</div>
main.ts
import { Component, ViewChild, ComponentFactoryResolver, ViewContainerRef } from '#angular/core';
import { my_component } from './my_component';
#Component({
selector: 'page-main_page',
templateUrl: 'main_page.html'
})
export class main_page {
#ViewChild('main', { read: ViewContainerRef }) entry: ViewContainerRef;
data: any;
constructor(public resolver: ComponentFactoryResolver,
public mine: my_component ){
};
ngOnInit(){
this.getDynamicREST().then((res)=>{
this.mine.data = res;
const factory = this.resolver.resolveComponentFactory(my_component);
this.entry.createComponent(factory);
})
};
}
my_component.ts
import { Component } from '#angular/core';
#Component({
selector: 'my_component ',
template: '<div class="my_component">{{data}}</div>'
})
export class my_component {
data: any;
}
How would I achieve this so that I can fetch angular components dynamically and display them?
Any help will be much appreciated.
Thank you.
You're on the right path. I ran into this very same scenario just a few months ago, here is the solution to accomplish your goals.
Here I attached a StackBlitz if you want to see the code running live and have a chance to play with it. Dynamic components can be a challenge to understand at first.
Live Demo
app.component.ts
This component acts as the container to the dynamic component and is where it will be created.
import {
Component, ViewChild, OnInit, OnDestroy,
AfterViewInit, ComponentFactoryResolver,
Input, Compiler, ViewContainerRef, NgModule,
NgModuleRef, Injector
} from '#angular/core';
import { CommonModule } from '#angular/common';
import { BrowserModule } from '#angular/platform-browser';
#Component({
selector: 'app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
#ViewChild('vc', { read: ViewContainerRef }) _container: ViewContainerRef;
private cmpRef;
constructor(
private componentFactoryResolver: ComponentFactoryResolver,
private compiler: Compiler,
private _injector: Injector,
private _m: NgModuleRef<any>) { }
ngOnInit() { }
ngAfterViewInit() {
let myTemplate = `<h2> Generated on the fly</h2>
<p>You can dynamically create your component template!</p>`
#Component({
template: myTemplate
})
class dynamicComponent {
constructor(){}
}
#NgModule({
imports: [
BrowserModule
],
declarations: [dynamicComponent]
})class dynamicModule {};
const mod = this.compiler.compileModuleAndAllComponentsSync(dynamicModule);
const factory = mod.componentFactories.find((comp) =>
comp.componentType === dynamicComponent
);
this.cmpRef = this._container.createComponent(factory);
}
ngOnDestroy() {
if (this.cmpRef) {
this.cmpRef.destroy();
}
}
}
Then in the template for your app component
app.component.html
<ng-template #vc></ng-template>
Then in your app.module you need to import the compiler and declare it as a provider:
app.module.ts
import {Compiler, COMPILER_OPTIONS, CompilerFactory} from '#angular/core';
import {JitCompilerFactory} from '#angular/platform-browser-dynamic';
export function createCompiler(compilerFactory: CompilerFactory) {
return compilerFactory.createCompiler();
}
#NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
RouterModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
routing
],
providers: [
{provide: COMPILER_OPTIONS, useValue: {}, multi: true},
{provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS]},
{provide: Compiler, useFactory: createCompiler, deps: [CompilerFactory]}
],
bootstrap: [AppComponent]
})
export class AppModule {}
*** Edit for 'tap' question
What you want to do is bind to the (click) event, I am not aware of any (tap) events and there are none listed in the Events reference by MDN Events Reference MDN
In your dynamic component add the following:
let myTemplate = `<h2> Generated on the fly</h2>
<p>You can dynamically create your component template!</p>
<div class="test" (click)="test();">Test</div>`
#Component({
template: myTemplate
})
class dynamicComponent {
constructor(){}
public test(){
alert("I've been clicked!");
}
}
Note I updated the StackBlitz if you want to see it in action!

ERROR Error: Uncaught (in promise): TypeError: users is undefined

I have an error in this Component and that error is not caught by command prompt.
Dashboard.component.ts
import { Component, OnInit } from '#angular/core';
import { User } from './user.component';
import { UserService } from './user.service';
#Component({
selector : 'dashboard',
templateUrl : './views/dashboard-component.html',
styleUrls: ['./views/css/dashboard-component.css'],
providers: [UserService]
})
export class DashboardComponent {
users: User[] = [];
constructor(private userservice: UserService){}
ngOnInit() : void{
this.userservice.getusers().then(users => this.users = users.slice(1,5) );
}
}
I can't understand what the problem is because i have defined "users" in the class.
The method is called from this service.
user.service.ts
import { Injectable } from '#angular/core';
import { User } from './user.component';
import { USERS } from './mock-users';
import { Headers, Http } from '#angular/http';
import 'rxjs/add/operator/toPromise';
#Injectable()
export class UserService {
private usersUrl = "http://localhost/user/src/app/userlist.php";
constructor(private http: Http) { }
getusers() : Promise<User[]>{
return this.http.get(this.usersUrl)
.toPromise()
.then(response => response.json().data as User[])
.catch(this.handleError);
}
getuser(id: number): Promise<User> {
const url = '${this.usersUrl}/${id}';
return this.http.get(url)
.toPromise()
.then(response => response.json().data as User)
.catch(this.handleError);
}
private handleError(error : any): Promise<any> {
console.error('an error occured', error);
return Promise.reject(error.message || error);
}
}
The data I am getting is :
[{"id":"1","fname":"Vishwas","lname":"Jadav","email":"vjadav#live.com","dpic":"2017-10-7--09-12-19.jpeg","phone":"7621823474","passw":"illj123","type":"2"}]
You don't have a data property in your response, as we can see you are simply getting an array, so you should return that. So in your service method getusers, instead of...
.then(response => response.json().data as User[])
do:
.then(response => response.json() as User[])
Sidenote, you might have the same problem with your getuser (?) just for future reference if you run into same problem there :)
Try assigning to array and then remove
ngOnInit() : void{
this.userservice.getusers().then(users => this.users = users;
this.users =this.users.slice(1,5);
});

Angular2 http get error

I am brand new in Angular2 framework and I have a problem with http get request. I want to display all registered users on my homepage.
This is my code:
home.service.ts
import { Injectable } from '#angular/core';
import { Http, Response } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class UserService {
constructor (
private http: Http
) {}
getUser() {
return this.http.get(`/app/home/home.php`)
.map((res:Response) => res.json());
}
}
home.component.ts:
// Imports
import { Component, OnInit } from '#angular/core';
import { UserService } from './home.service';
#Component({
templateUrl: './home.component.html'
})
// Component class implementing OnInit
export class HomeComponent{
// Private property for binding
constructor(private userService: UserService) {}
profile = {};
loadUser() {
this.userService.getUser().subscribe(data => this.profile = data);
}
}
home.php
<?php
$connection = new mysqli("127.0.0.1", "root", "", "flatmate");
if($connection->connect_error){
echo $connection->connect_error;
}
/* change character set to utf8 */
if (!$connection->set_charset("utf8")) {
echo $connection->error;
exit();
}
$getUser = 'SELECT * from users';
$result = mysqli_query($connection, $getUser);
$data = array();
while ($row = mysqli_fetch_array($result)) {
$data[] = $row;
}
echo json_encode($data);
home.component.html:
<div>
<button (click)="loadUser()">Load profile</button>
{{ profile | json }}
</div>
In my app.module.ts I added UserService provider. I prepared my code based on this tutorial. When I pass into get method URL from this example, code works properly. But if I change link to my home.php I get the error:
"errors.ts:42 ERROR SyntaxError: Unexpected token < in JSON at position 0"

Categories