Places Data from Google API Refresh Late in Ionic 4 - google-places-api

I am writing an itinerary app to add the points search by google places API. I can get the list of places successfully and list out in console. But the data will be shown on the screen after 5 seconds or more.
Any hints to have the data shown right after the list retrieved from google?
The html code
<ion-content padding>
<ion-item>
<ion-input placeholder="{{ 'itinerary-search.name' | translate }}" [(ngModel)]="googleName" id="name"></ion-input>
<ion-button slot="end" (click)="textSearch()">
<ion-icon slot="icon-only" name="search"></ion-icon>
</ion-button>
</ion-item>
<ion-card *ngFor="let placesServiceResult of placesServiceResults">
<ion-item>
<ion-label class="ion-text-wrap">{{ placesServiceResult.name }}</ion-label>
</ion-item>
<ion-item>
<ion-label class="ion-text-wrap">{{ placesServiceResult.formatted_address }}</ion-label>
</ion-item>
<ion-item>
<ion-button slot="start">
<ion-icon slot="icon-only" name="map"></ion-icon>
</ion-button>
<ion-button slot="end">
<ion-icon slot="icon-only" name="add"></ion-icon>
</ion-button>
</ion-item>
</ion-card>
<ion-fab horizontal="end" (click)="scrollToTop()">
<ion-fab-button size="small"><ion-icon name="arrow-dropup"></ion-icon></ion-fab-button>
</ion-fab>
<div #map id="map" style="display: none;"></div>
</ion-content>
After input a name and click the search button, the card will be shown after 5 seconds or more
The textSearch function
async textSearch() {
console.log('ItinerarySearchPage textSearch');
const queryRequest = {
query: this.googleName
};
this.placesServiceResults = [];
this.placesServiceQuery = new google.maps.places.PlacesService(this.googleMap);
await this.placesServiceQuery.textSearch(queryRequest, async (queryResults, queryStatus) => {
console.log('ItinerarySearchPage textSearch queryStatus=', queryStatus);
console.log('ItinerarySearchPage textSearch queryResults=', queryResults);
if (queryStatus === google.maps.places.PlacesServiceStatus.OK) {
await queryResults.forEach(element => {
const placeResult: PlaceResult = {
formatted_address: null,
geometry_location_lat: null,
geometry_location_lng: null,
icon: null,
name: null,
place_id: null
};
const formattedAddress = element.formatted_address;
const geometryLocationLat = element.geometry.location.lat();
const geometryLocationLng = element.geometry.location.lng();
const icon = element.icon;
const name = element.name;
const placeId = element.place_id;
placeResult.formatted_address = formattedAddress;
placeResult.geometry_location_lat = geometryLocationLat;
placeResult.geometry_location_lng = geometryLocationLng;
placeResult.icon = icon;
placeResult.name = name;
placeResult.place_id = placeId;
this.placesServiceResults.push(placeResult);
});
await console.log('ItinerarySearchPage textSearch placesServiceResults=', this.placesServiceResults);
} else {
if (this.storageLanguage === Language.english) {
this.toastProvider.presentWarningToast(ToastMessage.enSearchPlaceQueryFail);
} else {
this.toastProvider.presentWarningToast(ToastMessage.zhSearchPlaceQueryFail);
}
}
});
}

remove await and make it as sync
await queryResults.forEach(element => {...}
to
queryResults.forEach(element => {...}

Related

Getting Invariant Violation : invariant violation 47 on mutation query in appolo graphql

I am using a mutation query to take the input from user and update it in database but while updating it is throwing this error invariant violation which I am not able to understand, In mutation I have four objects with min and max value that is coming from user:
export const ADD_INSIGHT_META_DATA = gql`
mutation MyMutation ($data : [projectInsightsMetadata_insert_input!]!) {
insert_projectInsightsMetadata(objects: $data) {
returning {
id
createdAt
}
}
}
`
This is how I am using the above query :
export const updateScheduleInsightMetaData = async(InsertData:any )=>{
const response:ApolloQueryResult<any> = await client.query({
query:ADD_INSIGHT_META_DATA,
context:{
role:"updateMasterPlan",
token:getProjectExchangeToken()
},
fetchPolicy: 'network-only',
variables:{
data:InsertData
}
})
return response.data;
}
Now I am using updateScheduleInsightMetaData function in one of code :
import React, { useContext, useEffect, useState } from "react";
import { IconButton, makeStyles, Paper, TextField, Typography } from "#material-ui/core";
import { useParams } from "react-router-dom";
import { Button } from "#material-ui/core";
import { Box } from "#mui/system";
import {getScheduleInsightMetaData,updateScheduleInsightMetaData} from "./InsightsSettingsActions";
import { setIsLoading } from "src/modules/root/context/authentication/action";
import { stateContext } from "src/modules/root/context/authentication/authContext";
import Notification, { AlertTypes } from "src/modules/shared/components/Toaster/Toaster";
import { projectDetailsContext } from "src/modules/baseService/projects/Context/ProjectDetailsContext";
import {
decodeExchangeToken,
getProjectExchangeToken
} from "../../../../../services/authservice";
import "./InsightsSettings.scss";
import NoDataMessage from "src/modules/shared/components/NoDataMessage/NoDataMessage";
interface Params {
projectId:any
}
interface InputType{
min:number,
max:number
}
export const noPermissionMessage = "You don't have permission to view project insight settings";
const InsightsSettings: React.FC =()=>{
const { projectDetailsState }: any = useContext(projectDetailsContext);
const { dispatch, stateCont }: any = useContext(stateContext);
const {projectId} = useParams<Params>();
const [hasCreateAccess, setCreateAccess] = useState<boolean>(false);
const [informationalConstraints, setInformationalConstraints] = useState<any>({min:Number(""),max:Number("")});
const [rfiResponse, setRfiResponse] = useState<any>({min:Number(""),max:Number("")});
const [physicalConstraints, setPhysicalConstraints] = useState<any>({min:Number(""),max:Number("")});
const [managementConstraints, setManagementConstraints] = useState<any>({min:Number(""),max:Number("")});
const tenantId = decodeExchangeToken().tenantId;
console.log("informationalConstraints",informationalConstraints);
console.log("rfiResponse",rfiResponse);
console.log("physicalConstraints",physicalConstraints);
console.log("managementConstraints",managementConstraints);
const projectToken = getProjectExchangeToken();
useEffect(()=>{
setCreateAccess(decodeExchangeToken(projectToken).allowedRoles.includes("viewMasterPlan"))
},[projectToken])
const navigateback = () => {
// props.navBack();
}
useEffect(()=>{
const token = projectDetailsState.projectToken;
fetchInsightsData(projectId,tenantId,token)
},[projectId,tenantId])
const fetchInsightsData = async(projectId:any,tenantId:any,token:any)=>{
try{
// const tenantId = decodeExchangeToken().tenantId;
// const token = projectDetailsState.projectToken;
dispatch(setIsLoading(true));
const res = await getScheduleInsightMetaData(projectId, tenantId ,token)
dispatch(setIsLoading(false));
}catch(err){
console.log("error in fetching insights metadata",err)
Notification.sendNotification('An error occured while fetching insights metadata', AlertTypes.warn);
dispatch(setIsLoading(false));
}
}
const handleInformationalInputChange = (e:any)=>{
setInformationalConstraints((prevState:any)=>({...prevState,[e.target.name]:Number(e.target.value)}))
}
const handleRfiInputChange = (e:any)=>{
setRfiResponse((prevState:any)=>({...prevState,[e.target.name]:Number(e.target.value)}))
}
const handlePhysicalInputChange = (e:any)=>{
setPhysicalConstraints((prevState:any)=>({...prevState,[e.target.name]:Number(e.target.value)}))
}
const handleManagementInputChange = (e:any)=>{
setManagementConstraints((prevState:any)=>({...prevState,[e.target.name]:Number(e.target.value)}))
}
const handleUpdate = async(e:any,informationalConstraints:any,rfiResponse:any,physicalConstraints:any,managementConstraints:any)=>{
try{
dispatch(setIsLoading(true));
const data = {
LeadtimeMgmntConstraints:managementConstraints,
LeadtimePhysicalConstraints:physicalConstraints,
ChangeOrderIssueReview:rfiResponse,
RFIReviewResponse:informationalConstraints
}
const response = await updateScheduleInsightMetaData(data)
// const response = await updateScheduleInsightMetaData(managementConstraints,physicalConstraints,rfiResponse,informationalConstraints)
Notification.sendNotification("Successfully updated insights", AlertTypes.success);
dispatch(setIsLoading(false));
}catch(err){
dispatch(setIsLoading(false));
Notification.sendNotification(err, AlertTypes.warn);
console.log(err)
}
}
return(
<>
{hasCreateAccess?
<div className="InsightsSettings">
<>
<div className="InsightsSettings__header">
<Typography component="p">Insight Settings</Typography>
</div>
<div className="InsightsSettings__input_area">
<div className="InsightsSettings__individual_box">
<Typography component="p">How far ahead of an activity start does the team review and resolve management or informational constraints?</Typography>
<div className="InsightsSettings__constraints">
<input name="min" className="InsightsSettings__constraints__style" value={informationalConstraints.min} placeholder="min" onChange={handleInformationalInputChange}/>
<input name="max" className="InsightsSettings__constraints__style" value={informationalConstraints.max} placeholder="max" onChange={handleInformationalInputChange}/>
</div>
</div>
<div className="InsightsSettings__individual_box">
<Typography component="p">What is the average (or typical) RFI design response period for this project?</Typography>
<div className="InsightsSettings__constraints">
<input name="min" className="InsightsSettings__constraints__style" value={rfiResponse.min} placeholder="min" onChange={handleRfiInputChange}/>
<input name="max" className="InsightsSettings__constraints__style" value={rfiResponse.max} placeholder="max" onChange={handleRfiInputChange}/>
</div>
</div>
<div className="InsightsSettings__individual_box">
<Typography component="p">How far ahead of an activity start does the team review and resolve physical or site constraints ?</Typography>
<div className="InsightsSettings__constraints">
<input name="min" className="InsightsSettings__constraints__style" value={physicalConstraints.min} placeholder="min" onChange={handlePhysicalInputChange}/>
<input name="max" className="InsightsSettings__constraints__style" value={physicalConstraints.max} placeholder="max" onChange={handlePhysicalInputChange}/>
</div>
</div>
<div className="InsightsSettings__individual_box">
<Typography component="p">How far ahead of an activity start does the team review and resolve management or informational constraints?</Typography>
<div className="InsightsSettings__constraints">
<input name="min" className="InsightsSettings__constraints__style" value={managementConstraints.min} placeholder="min" onChange={handleManagementInputChange}/>
<input name="max" className="InsightsSettings__constraints__style" value={managementConstraints.max} placeholder="max" onChange={handleManagementInputChange}/>
</div>
</div>
</div>
</>
<div className="InsightsSettings__action-button">
<Button data-testid={'cancel-update'} variant="outlined" onClick={navigateback} className="cancel-button">
Cancel
</Button>
<Button
variant="outlined"
className="update-button"
onClick={(e:any)=>{handleUpdate(e,informationalConstraints,rfiResponse,physicalConstraints,managementConstraints)}}
>
Update
</Button>
</div>
</div>: (
<div className="noCreatePermission-insight">
<div className="no-permission-insight">
<NoDataMessage message={noPermissionMessage}/>
</div>
</div>
) }
</>
)
}
export default InsightsSettings
When I am clicking on update button to make the insertion in database I am getting invariant violation: 47 error ,I am pasting the error here
Invariant Violation: Invariant Violation: 47 (see https://github.com/apollographql/invariant-packages)
at new InvariantError (http://localhost:3000/static/js/vendors~main.chunk.js:327507:24)
at invariant (http://localhost:3000/static/js/vendors~main.chunk.js:327521:11)
at getQueryDefinition (http://localhost:3000/static/js/vendors~main.chunk.js:9716:230)
at StoreReader.diffQueryAgainstStore (http://localhost:3000/static/js/vendors~main.chunk.js:2449:286)
at InMemoryCache.diff (http://localhost:3000/static/js/vendors~main.chunk.js:1132:29)
at http://localhost:3000/static/js/vendors~main.chunk.js:4864:28
at perform (http://localhost:3000/static/js/vendors~main.chunk.js:1264:31)
at InMemoryCache.batch (http://localhost:3000/static/js/vendors~main.chunk.js:1288:7)
at InMemoryCache.performTransaction (http://localhost:3000/static/js/vendors~main.chunk.js:1321:17)
at QueryInfo.markResult (http://localhost:3000/static/js/vendors~main.chunk.js:4842:20)
at http://localhost:3000/static/js/vendors~main.chunk.js:5713:19
at both (http://localhost:3000/static/js/vendors~main.chunk.js:10788:20)
at http://localhost:3000/static/js/vendors~main.chunk.js:10777:26
at new Promise (<anonymous>)
at Object.then (http://localhost:3000/static/js/vendors~main.chunk.js:10776:16)
at Object.next (http://localhost:3000/static/js/vendors~main.chunk.js:10791:39)
at notifySubscription (http://localhost:3000/static/js/vendors~main.chunk.js:332559:18)
at onNotify (http://localhost:3000/static/js/vendors~main.chunk.js:332603:3)
at SubscriptionObserver.next (http://localhost:3000/static/js/vendors~main.chunk.js:332652:5)
at http://localhost:3000/static/js/vendors~main.chunk.js:10848:23
at Array.forEach (<anonymous>)
at iterateObserversSafely (http://localhost:3000/static/js/vendors~main.chunk.js:10847:23)
at Object.next (http://localhost:3000/static/js/vendors~main.chunk.js:10586:87)
at notifySubscription (http://localhost:3000/static/js/vendors~main.chunk.js:332559:18)
at onNotify (http://localhost:3000/static/js/vendors~main.chunk.js:332603:3)
at SubscriptionObserver.next (http://localhost:3000/static/js/vendors~main.chunk.js:332652:5)
at Object.next (http://localhost:3000/static/js/vendors~main.chunk.js:6773:22)
at notifySubscription (http://localhost:3000/static/js/vendors~main.chunk.js:332559:18)
at onNotify (http://localhost:3000/static/js/vendors~main.chunk.js:332603:3)
at SubscriptionObserver.next (http://localhost:3000/static/js/vendors~main.chunk.js:332652:5)
at notifySubscription (http://localhost:3000/static/js/vendors~main.chunk.js:332559:18)
at onNotify (http://localhost:3000/static/js/vendors~main.chunk.js:332603:3)
at SubscriptionObserver.next (http://localhost:3000/static/js/vendors~main.chunk.js:332652:5)
at http://localhost:3000/static/js/vendors~main.chunk.js:7061:18
After going to the github url provided in error i.e https://github.com/apollographql/invariant-packages it tells to go into particular file in your node-modules to get the more understanding of invariant number error
node_modules/#apollo/client/invariantErrorCodes.js
after going into above file they have provided some extra information related to error code so for me I was getting invariant violation: 47
47: {
file: "#apollo/client/utilities/graphql/getFromAST.js",
node: invariant(queryDef && queryDef.operation === 'query', 'Must contain a query definition.')
},
In my case I am having mutation query and trying to query it instead of doing mutation that's why I was getting error so the changes that I did in my code to make it working is :
Instead of doing this:
export const updateScheduleInsightMetaData = async(InsertData:any )=>{
const response:ApolloQueryResult<any> = await client.query({
query:ADD_INSIGHT_META_DATA,
context:{
role:"updateMasterPlan",
token:getProjectExchangeToken()
},
fetchPolicy: 'network-only',
variables:{
data:InsertData
}
})
return response.data;
}
I needed to do this:
export const updateScheduleInsightMetaData = async(InsightsData:any )=>{
const response = await client.mutate({
mutation:ADD_INSIGHT_META_DATA,
context:{
role:"updateMasterPlan",
token:getProjectExchangeToken()
},
fetchPolicy: 'network-only',
variables:{
data:InsightsData
}
})
return response.data;
}

Draftjs mentions plugin with scroll

The issue is keydown/keyup aren't working when mention list popup has scroll , i can scroll using mouse but keyup/keydown aren't making the scroll move to the right position
This can be achieved by custom entry Component ->
const entryComponent = (props:any) => {
const { mention, isFocused, searchValue, ...parentProps } = props;
const entryRef = React.useRef<HTMLDivElement>(null);
useEffect(() => {
if (isFocused) {
if (entryRef.current && entryRef.current.parentElement) {
entryRef.current.scrollIntoView({
block: 'nearest',
inline: 'center',
behavior: 'auto'
});
}}
}, [isFocused]);
return (
<>
<div
ref={entryRef}
role='option'
aria-selected={(isFocused ? 'true' : 'false')}
{...parentProps}>
<div className={'mentionStyle'}>
{mention.name}
</div>
</div>
</> );
};

Make searchbar works

how can i do, i want mi searchbar works, im doing an app, on IONIC VSCODE
Here my
HTML HERE I WANT THE SEARCHBAR WORKS
<ion-item *ngFor="let interes of interesesObj">
<ion-label>{{interes.Nombre}}</ion-label>
<ion-checkbox slot="start" [(ngModel)] ="interes.isChecked"></ion-checkbox>
AND HERE THE SEARCHBAR
<ion-item>
<ion-searchbar
[(ngModel)]="miBuscador"
[showCancelButton]="miStringDeCancell"
(ionInput)="onInput($event)"
(ionCancel)="onCancel($event)">
</ion-searchbar>
`
In HTML
<ion-searchbar mode="ios" [(ngModel)]="searchTerm" (ionClear)="setFilteredItems()"
(ionChange)="getItems($event)" placeholder="Search Topic"></ion-searchbar>
In Ts
getItems(query) {
console.log(query)
this.resetChanges();
this.posts = this.filterItems(query.detail.value);
}
protected resetChanges = () => {
this.posts = this.dummyPost;
};
setFilteredItems() {
//console.log('clear')
this.posts = [];
this.posts = this.posts;
}
filterItems(searchTerm) {
return this.posts.filter((item) => {
return item.title.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1;
});
}

how to get click working in redux-react component with enzyme

Try to test click event to increase a value in the redux state. But the counter value is always 0.
Counter render
render() {
const { counter, label, isSaving, isLoading, error } = this.props
return <form>
<legend>{label}</legend>
<pre>{JSON.stringify({ counter, isSaving, isLoading }, null, 2)}</pre>
<button ref='increment' onClick={this._onClickIncrement}>click me!</button>
<button ref='save' disabled={isSaving} onClick={this._onClickSave}>{isSaving ? 'saving...' : 'save'}</button>
<button ref='load' disabled={isLoading} onClick={this._onClickLoad}>{isLoading ? 'loading...' : 'load'}</button>
{error ? <div className='error'>{error}</div> : null}
</form>
}
Jest Test
let container, store
beforeEach(() => {
store = mockStore(initialState)
container = shallow(<Counter label='a counter!' store={store} />)
})
it('+++ check Props after increments counter', () => {
const mockClick = jasmine.createSpy('click');
expect(container.find('button').at(0).type()).toEqual('button');
const increment = container.find('button').at(0)
container.find('button').at(0).simulate('click')
container.find('button').at(0).simulate('click')
container.find('button').at(0).simulate('click')
const pre = container.find('pre');
// const pre = TestUtils.findRenderedDOMComponentWithTag(counter, 'pre')
console.log(container.props().counter);
// expect(JSON.parse(counter.find('pre').first.text()).counter.value).toEqual(3)
})

Angular2 - Display image

I created a Angular2 app that allows the user to upload images. I want to implement a preview option. However, when i try to imperilment it the image doesn't show up. How do i achieve this feature?
UploadComponent.ts
import * as ng from '#angular/core';
//import { UPLOAD_DIRECTIVES } from 'ng2-uploader';
import {UploadService} from '../services/upload.service';
#ng.Component({
selector: 'my-upload',
providers:[UploadService],
template: require('./upload.html')
})
export class UploadComponent {
progress:any;
logo:any;
filesToUpload: Array<File>;
constructor(public us:UploadService){
this.filesToUpload = [];
}
upload() {
this.us.makeFileRequest("http://localhost:5000/api/SampleData/Upload", this.filesToUpload)
.then((result) => {
console.log(result);
}, (error) => {
console.error(error);
});
}
onFileChange(fileInput: any){
this.logo = fileInput.target.files[0];
}
}
Upload.html
<h2>Upload</h2>
<input type="file" (change)="onFileChange($event)" placeholder="Upload image..." />
<button type="button" (click)="upload()">Upload</button>
<img [src]="logo" alt="Preivew">
The way you try it, you don't get the image URL with fileInput.target.files[0], but an object.
To get an image URL, you can use FileReader (documentation here)
onFileChange(fileInput: any){
this.logo = fileInput.target.files[0];
let reader = new FileReader();
reader.onload = (e: any) => {
this.logo = e.target.result;
}
reader.readAsDataURL(fileInput.target.files[0]);
}
filesToUpload: Array<File> = [];
url: any;
image: any;
//file change event
filechange(fileInput: any) {
this.filesToUpload = <Array<File>>fileInput.target.files;
this.image = fileInput.target.files[0]['name'];
this.readurl_file(event);
}
//read url of the file
readurl_file(event) {
if (event.target.files && event.target.files[0]) {
const reader = new FileReader();
reader.onload = (eve: any) => {
this.url = eve.target.result;
};
reader.readAsDataURL(event.target.files[0]);
}
}
<div class="form-group">
<label for="image">Image</label>
<input type="file" class="form-control" (change)="filechange($event)" placeholder="Upload file..." >
</div>
<div class="container">
<img [src]="url">
</div>
Using FileReader is not a good practice. If an image is too large it can crash your browser because onload function load whole image in RAM.
Better approach is to use:
url = URL.createObjectURL($event.target.files[0]);
Then, show it out with DomSanitizer:
this.sanitizer.bypassSecurityTrustUrl(url)
So in ts:
constructor(private sanitizer: DomSanitizer) {}
onFileChange(fileInput: any){
this.url = URL.createObjectURL($event.target.files[0]);
}
get previewUrl(): SafeUrl {
return this.sanitizer.bypassSecurityTrustUrl(this.url);
}
And in html:
<img [src]="previewUrl"/>

Resources