-2

Am trying to create a user query with Dexie where the user queries the database in their own but i cant get it to work.

<!-- html -->

<div class="window" style="padding-top: 1.5rem;">
<link rel="stylesheet" type="text/css" href="./css/bootstrap-grid.min.css">
 <div class="window-content">
   <div class="pane-group">
       <div class="pane" style="padding:4rem;padding-top: 0 ">
           <h3 class="text-center"><u><span class="icon icon icon-code icon-text" style="color:#4e5851;padding-right:1rem "></span>Advanced Queries</u></h3>
           <table class="table-striped mb-2">
               <thead>
               <tr>
                   <th colspan="3"><input class="form-control" type="" name="query" id="query"></th>
                   <th style="width:4rem"><button class="btn btn-default" id="run">
                       <span class="icon icon-search"></span>
                   </button></th>
               </tr>
           </thead>
           </table>
           <div class ="row" style="display: flex" id='display_body'>

           </div>
       </div>
   </div>
</div>
</div>

//script

document.querySelector('#run').addEventListener("click", function(){
const { init_data} = require('../res/reusable');
var db = init_data(Dexie);
let torun = document.querySelector('#query').value; 
let mangoArray=torun.split('.')
//console.log('mangoArray');
if (mangoArray.length== '1') {
    db[mangoArray[0]].each(item=>{
        console.log(item);
});

}else if(mangoArray.length== '2'){
db[mangoArray[0]][mongoArray[1]].each(item=>{
console.log(item);
});
}
});

When i input devices in input (a table in the dexie database it works) in full it should run db.devices.each

However i cant get functions to work inside the dexie class. so when i input devices.orderBy('name') i get undefined error

//error
Uncaught TypeError: Cannot read property 'each' of undefined

How do i achieve this?

xaander1
  • 1,064
  • 2
  • 12
  • 40
  • down vote really! what stack overflow rule did i break? – xaander1 Jan 08 '20 at 10:23
  • The error message means you are trying to run `each` function from `undefined` instance. `db[mangoArray[0]]` or `db[mangoArray[0]][mongoArray[1]]` returns undefined. Debug it – OlegI Jan 08 '20 at 10:45
  • `db[mangoArray[0]]` runs okay the second doesnt check here for the first https://stackoverflow.com/questions/59220777/is-it-possible-to-use-square-bracket-notion-in-class-methods – xaander1 Jan 08 '20 at 11:35
  • err more downvote no one seems to believe me but someone try it its a genuine problem i am facing. Its not a logical error – xaander1 Jan 08 '20 at 11:47
  • "When i input devices in input". Cool first, if you want someone takes time to help you then you should also take your time to improve your question and add all relevant parameters instead of throwing 1-2 sentences and your complete source code – Ling Vu Jan 08 '20 at 12:26
  • i tried adding as much information as i can...infact you just need to change the database for it to work...next time ill add a fiddle – xaander1 Jan 08 '20 at 12:27
  • i meant in input field....next time ill include a fiddle and try to make it short – xaander1 Jan 08 '20 at 12:33

1 Answers1

1

First of all, the thing you try to do is quite dangerous; giving a user an ability to perform an arbitrary query on the database from the front-end of your app. I advise caution.

Second of all - the error says it all - you cannot call a method each() on undefined. What is undefined then? See, when your query looks like this: devices.orderBy('name'), the code executes the following:

let mangoArray=torun.split('.') // ["devices", "orderBy('name')"]
...
}else if(mangoArray.length== '2'){
db[mangoArray[0]][mongoArray[1]]
// ^ now pay attention: db["devices"]["orderBy('name')"]
.each(item=>{
  console.log(item);
});

So, while the db object has an attribute field devices, it certainly does not have orderBy('name'). If you want to call the method of this object, there are several ways to deal with this. The easiest (but the most dangerous) would be to skip the splitting and handle this with eval:

const query = eval(`db.${torun}`)
query.each(...)

But this allows a user to do whatever he wants with your data - delete, modify, corrupt, etc. The more safe way would be to use some quite complex regex validation on the input.

The safest, and most advised, would be to actually develop a user-friendly interface that allows the user to access your data with full control. Make some forms that let user choose which data he wants to get, how to order them, filter them, then send this data through a server and return adequate response. This is called "hiding implementation" - your app's user don't need to know which database you are using, let alone the API of this database!

Hope this helps.

Maciej B. Nowak
  • 1,180
  • 7
  • 19