Get Level Information of non-revit model - NWC - data-visualization

I could not use the extension of level information(Autodesk.AEC.LevelsExtension) directly and I tried to use a workaround which is described below link.
https://forge.autodesk.com/blog/add-data-visualization-heatmaps-rooms-non-revit-model-part-i-nwc
However, it did not work for me. I tried it as in the below code. But, when i tried to print length of the dbIds it returns zero. So, I could not fill the levels. What can be the problem and why the layer searching is not worked?
async function findLevels(model) {
return new Promise((resolve, reject) => {
viewer.model.search(
'Layer',
(dbIds) => {
const levels = [];
const tree = viewer.model.getData().instanceTree;
console.log('Db Ids: ' + dbIds.length);
for( let i=0; i<dbIds.length; i++ ) {
const dbId = dbIds[i];
const name = tree.getNodeName( dbId );
if( name.includes( '<No level>' ) ) continue;
levelsGeo.push({
guid: dbId,
name,
dbId,
extension: {
buildingStory: true,
structure: false,
computationHeight: 0,
groundPlane: false,
hasAssociatedViewPlans: false,
}
});
}
resolve(levelsGeo);
},
reject,
['Icon']
);
});
}

Related

How do I resolve a callback error with 'callback' is an instance of Object)?

TypeError: callback is not a function. (In 'callback(data)',
'callback' is an instance of Object)
The code here works just fine when I write it like this:
const onSelectFilterDone = (filter) => {
setFilter(filter);
setFilterModalVisible(false);
unsubscribe.current = listingsAPI.subscribeListings(
{ categoryId: category.id },
// { categoryId2: category2.id },
favorites,
onListingsUpdate,
);
};
When i uncomment that other line, it breaks and gives me this error.
const onSelectFilterDone = (filter) => {
setFilter(filter);
setFilterModalVisible(false);
unsubscribe.current = listingsAPI.subscribeListings(
{ categoryId: category.id },
{ categoryId2: category2.id },
favorites,
onListingsUpdate,
);
};
Here is the relevant snippet from listingsAPI (below) if it helps but this code works fine when there is only one object. Is there a specific way to make this work with two objects like above?
if (categoryId) {
return (
listingsRef
.where('categoryID', '==', categoryId)
.where('isApproved', '==', isApproved)
.onSnapshot((querySnapshot) => {
const data = [];
querySnapshot.forEach((doc) => {
const listing = doc.data();
if (favorites && favorites[doc.id] === true) {
listing.saved = true;
}
data.push({ ...listing, id: doc.id });
});
callback(data);
})
);
}
if (categoryId2) {
return (
listingsRef
.where('categoryID2', '==', categoryId2)
.where('isApproved', '==', isApproved)
.onSnapshot((querySnapshot) => {
const data = [];
querySnapshot.forEach((doc) => {
const listing = doc.data();
if (favorites && favorites[doc.id] === true) {
listing.saved = true;
}
data.push({ ...listing, id: doc.id });
});
callback(data);
})
);
}
You can combine your queries via this way if you want to have it optional:
let query = listingsRef.where('isApproved', '==', isApproved)
if (categoryId) {
query = query.where('categoryID', '==', categoryId)
}
if (categoryId2) {
query = query.where('categoryID2', '==', categoryId2)
}
query.onSnapshot...

ngx-dropzone to load images from list

I am using ngx-dropzone with angular 8. I have used ngx-dropzone for uploading and it works but this time I want to load images from a specific list to dropzone. Here is my code.
<ngx-dropzone (change)="onSelect($event)">
<ngx-dropzone-label>Select/Drop images here!</ngx-dropzone-label>
<ngx-dropzone-image-preview ngProjectAs="ngx-dropzone-preview" [removable]="true" (removed)="onRemove(f)" *ngFor="let f of files" [file]="f">
<ngx-dropzone-label></ngx-dropzone-label>
</ngx-dropzone-image-preview>
</ngx-dropzone>
Here is my onSelect event which bindimages and push them into files array list.
onSelect(event) {
this.alertService.clear();
console.log(event.addedFiles);
this.files.push(...event.addedFiles);
if (this.files.length > 4) {
this.alertService.error('Please select only four images for each service.');
this.files = [];
} else {
this.bindImages();
}
}
bindImages() {
this.alertService.clear();
this.imageList = [];
this.files.forEach((x) => {
const file = x;
if (file.type.split('/')[0] !== 'image') {
this.alertService.error('Please select image to proceed further.');
return false;
}
if (file.size > 5242880) {
this.alertService.error('Image size must be equal to or less then 5 MB.');
return false;
}
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => {
const val = reader.result as string;
const items = [{Serviceimage: val, ServiceId: this.serviceId, SaloonId: this.saloonId}];
this.imageList.push(...items);
};
reader.onerror = (error) => {
console.log('Error: ', error);
return;
};
});
}
Here is the my api codes which returns me the list of images with base64 string
getImages() {
this.alertService.clear();
this.imageModel.SaloonId = this.saloonId;
this.imageModel.ServiceId = this.serviceId;
this.apiService.Create('Saloon/getServiceImages', this.imageModel).subscribe(
resp => {
if (resp.length > 0) {
// Here to load Images to dropzone.
}
console.log(this.files);
},
error => {
this.alertService.error('Error getting images. Please contact admin.');
},
() => { console.log('complete'); }
);
}
This image returns me the following list.

$nextTick running before previous line finished

I have a vue function call which is triggered when selecting a radio button but it seems that my code inside my $nextTick is running before my previous line of code is finished. I don't want to use setTimout as I don't know how fast the user connection speed is.
findOrderer() {
axios.post('/MY/ENDPOINT')
.then((response) => {
this.orderers = response.data.accounts;
console.log('FIND_ORDER', this.orderers)
...OTHER_CODE
}
rbSelected(value) {
this.findOrderer();
this.newOrderList = [];
this.$nextTick(() => {
for (var i = 0, length = this.orderers.length; i < length; i++) {
console.log('FOR')
if (value.srcElement.value === this.orderers[i].accountType) {
console.log('IF')
this.newOrderList.push(this.orderers[i]);
}
}
this.$nextTick(() => {
this.orderers = [];
this.orderers = this.newOrderList;
console.log('orderers',this.orderers)
})
})
}
Looking at the console log the 'FINE_ORDERER' console.log is inside the 'findOrderer' function call so I would have expected this to be on top or am I miss using the $nextTick
That's expected, since findOrderer() contains asynchronous code. An easy way is to simply return the promise from the method, and then await it instead of waiting for next tick:
findOrderer() {
return axios.post('/MY/ENDPOINT')
.then((response) => {
this.orderers = response.data.accounts;
console.log('FIND_ORDER', this.orderers);
});
},
rbSelected: async function(value) {
// Wait for async operation to complete first!
await this.findOrderer();
this.newOrderList = [];
for (var i = 0, length = this.orderers.length; i < length; i++) {
console.log('FOR')
if (value.srcElement.value === this.orderers[i].accountType) {
console.log('IF')
this.newOrderList.push(this.orderers[i]);
}
}
this.orderers = [];
this.orderers = this.newOrderList;
console.log('orderers',this.orderers)
}

Perform a POST request in the background using React Native (expo)

I am relatively new to React Native but I have a functional codebase. My app sends orders from the waiter to the kitchen. I have tested it in stores. What I need is to somehow post the order to my web app without waiting for the server to respond (assuming that all is ok) and navigate directly to the list of tables some sort of async/background job. Do I implement this using some background tasks? if yes could you point in the right direction? Also if possible no redux answers I don't know how to use it yet.
Sorry for the messy code I'm getting better.
onSendOrder = () => {
//console.log('Sending Order');
//console.log("table_id", this.props.navigation.getParam("table_id"));
// trim the contents.
let order_items = this.state.order;
// //console.log(order_items);
// const myArray = this.state.data.filter(function( obj ) {
// return obj.checked !== false;
// });
var i;
// let total_cost = 0;
let contents = []
// //console.log('total_cost: ', total_cost);
// let items = order.items;
for (i = 0; i < order_items.length; i++) {
contents = order_items[i].contents.filter(function( obj ) {
return obj.checked !== false;
});
// //console.log(contents);
order_items[i].contents = contents;
// total_cost += this.compute_item_cost(order[i]);
}
this.setState({loading:true});
//console.log('Trimed order items: ',order_items);
let order = {
"items": {
"credentials": this.state.credentials,
"personnel_id": 1,
"store_id": 1,
"order_comment": "",
"order_id": "",
"timestamp": "None",
"table_id": this.props.navigation.getParam("table_id"),
"order_items": order_items
}
};
var host = this.props.navigation.getParam('url', 'something.com');
// //console.log('SENDING ORDER TO HOST: ', host)
//console.log('ORDER OBJECT', order);
fetch("http://" + host + "/api/v1/mobile/order?store_id=1", {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(order)
})
.then(response => {
// //console.log(response.status)
// this.props.navigation.navigate('Table', { order: this.state.order });
const statusCode = response.status;
const data = response.json();
return Promise.all([statusCode, data]);
})
.then((server_response) => {
//console.log("RESULTS HERE:", server_response[0])
this.setState({
order: [],
}, function () {
if (server_response[0] == 201) {
//console.log('Success Going to Table')
this.props.navigation.navigate('Table', { order: this.state.order });
} else {
//console.log('Failed going to table')
this.props.navigation.navigate('Table', { order: this.state.order });
}
});
})
.catch((error) => {
//console.error(error);
})
};
}
import * as Notifications from 'expo-notifications';

Rewriting the Dataprovider for multiple api requests broke it and now returns the error "Cannot read property 'hasOwnProperty' of undefined"

I am using the react-admin package and it has come to my attention that I needed to rewrite my functioning data provider to merge two different api request results into one array of data before passing the data to the resource component that would display it. After my rewrite I console log the data being returned and it is correct, but no matter what I have tried I always get the "Cannot read property 'hasOwnProperty' of undefined" error before my console.log of the data, and then I get the same error message a few seconds later, and nothing gets displayed.
in dataprovider.js (displays the data in the resource component)
export default (type, resource, params) => {
var apiUrl = `https://request1url.com/api`;
let query = '';
let url = '';
const options = {
headers : new Headers({
Accept: 'application/json',
}),
};
switch (type) {
case GET_LIST: {
if(resource === 'errors'){
query = '/query/errors';
}
if(resource === 'people'){
query = '/query/users';
}
url = `${apiUrl}${query}`;
break;
}
default:
throw new Error(`Unsupported Data Provider request type ${type}`);
}
return fetch(url, options)
.then(res => {
return res.json()
})
.then(json => {
var data = [];
var result = json.data.result;
for(var i = 0; i < result.length; i++){
result[i].id = i
data.push(result[i])
}
}
console.log(data)
switch (type) {
case GET_LIST:
return {
data: data,
total: data.length
}
case GET_ONE:
return {
data: data,
}
default:
return { data: data};
}
});
};
in NEWdataprovider.js (rewrite)
export default (type, resource, params) => {
const apiRequests = ['https://request1url.com/api','https://request2url.com/api'];
let query = '';
const options = {
headers : new Headers({
Accept: 'application/json',
}),
};
switch (type) {
case GET_LIST: {
if(resource === 'errors'){
query = '/query/errors';
}
if(resource === 'people'){
query = '/query/users';
}
break;
}
default:
throw new Error(`Unsupported Data Provider request type ${type}`);
}
var req1 = fetch(`${apiRequests[0]}${query}`, options).then(function(response){
return response.json()
});
var req2 = fetch(`${apiRequests[1]}${query}`, options).then(function(response){
return response.json()
});
Promise.all([req1,req2]).then(function(values){
var data = [];
var result1 = values[0].data.result;
var result2 = values[1].data.result;
for(var i = 0; i < result1.length; i++){
result1[i].id = i
data.push(result1[i])
}
for(var j = 0; j < result2.length; j++){
result2[j].id = j
data.push(result2[j])
}
console.log(data)
switch (type) {
case GET_LIST:
return {
data: data,
total: data.length
}
default:
return { data: data};
}
});
};
in App.js
<Admin dataProvider={dataProvider}>
<Resource name="errors" list={errors} />
<Resource name="people" list={people} />
</Admin>
);
in the console.log the data logged is the correct format, and data to be displayed, but with the original dataprovider it displayed the list of items, and the new dataprovider returns the error message "Cannot read property 'hasOwnProperty' of undefined"
Your dataprovider needs to return a promise.
Per the docs...
/**
* Query a data provider and return a promise for a response
*
* #example
* dataProvider(GET_ONE, 'posts', { id: 123 })
* => Promise.resolve({ data: { id: 123, title: "hello, world" } })
*
* #param {string} type Request type, e.g GET_LIST
* #param {string} resource Resource name, e.g. "posts"
* #param {Object} payload Request parameters. Depends on the action type
* #returns {Promise} the Promise for a response
*/
const dataProvider = (type, resource, params) => new Promise();
Try return Promise.all() instead.
export default (type, resource, params) => {
const apiRequests = ['https://request1url.com/api','https://request2url.com/api'];
let query = '';
const options = {
headers : new Headers({
Accept: 'application/json',
}),
};
switch (type) {
case GET_LIST: {
if(resource === 'errors'){
query = '/query/errors';
}
if(resource === 'people'){
query = '/query/users';
}
break;
}
default:
throw new Error(`Unsupported Data Provider request type ${type}`);
}
var req1 = fetch(`${apiRequests[0]}${query}`, options).then(function(response){
return response.json()
});
var req2 = fetch(`${apiRequests[1]}${query}`, options).then(function(response){
return response.json()
});
return Promise.all([req1,req2]).then(function(values){
var data = [];
var result1 = values[0].data.result;
var result2 = values[1].data.result;
for(var i = 0; i < result1.length; i++){
result1[i].id = i
data.push(result1[i])
}
for(var j = 0; j < result2.length; j++){
result2[j].id = j
data.push(result2[j])
}
console.log(data)
switch (type) {
case GET_LIST:
return {
data: data,
total: data.length
}
default:
return { data: data};
}
});
};