I have been working on protractor for over two weeks now and have taken a liking towards it, but there's a certain problem that's been bugging me for a while:
What I want to do is: fetch values from database and use it in my tests, so I have been doing the following:
var test=function(callback)
{
//connection made;
//select query fired;
connection.query('select * from mytable', function(rows,error){
var result={};
for(int i=0;i<rows.length;i++)
{
result.first=rows[i].col1;
result.sec=rows[i].col2;
result.third=rows[i].col3;
callback(result);
}
});
}
//and then I use the return values as:
test(function(data){
var value1;
var value2;
value1=data.first;
value2=data.sec;
// i am able to print value1 and value2, the real problem is below:
browser.get(value1);//the browser function wont work!!
});
the spec passes with no failures,
I can print the values from the database but I am not able to use the browser functions.
Kindly help!!
Related
I work in laravel and trying to get the response from the page. This is the controller in question:
public function counter($id)
{
$toSearch = $id * 10000;
$latest = User::where('counter', '>=', $toSearch)->get()->last();
$res = $latest['counter'] % $toSearch;
return $res;
}
As you can see the result that been returned by the controller is a single record and I am desperate to getting that record in to the Java Script File in the separate file than my blade view. I don't want to access the data base from JS and just trying to get that single record.
This is the function that is responsible for returning the result:
function counter(id) {
let data;
// Please Help Me Here
return data;
}
The returned value from this function will be used for another function.
The way the algorithm work is calling the function counter form the JS file which the result will be handled by the controller by somewhat using fetch or anything.
Note: the result must be in integer <- perhaps there is another thing to do to convert it to integer / number.
I see 2 options of solving your problem:
1. Send variable to blade template and then with js retrieve it.
2. Make ajax request to retrieve the data, you need to create separate route, so the route only return result via JSON.
Both variants are having their cons and pros. For someone its easier second, forelse first. I'll try to write both down below:
1. Sending data to Blade - for this one you need to know where that counter will be used, if you trying to use it globally, then you might attach to body or footer/header as like:
<body data-counter="{{App\Http\Models\User::calculateCounter($user_id)}}">
its just example, your real code might be different. For above code you need to create public static function in User model and put your code there in Model. Also you have to pass $user_id variable and recieve it in User model. Or You may use controller file to acheive, though result would be the same ($user_id needs to send).
Then, in your js file's function:
function counter() {
return parseInt(document.body.dataset.counter);
}
2. Ajax request - you may have async await issue, if yes, then try to learn more about "returning response async XMLHTTPRequest". It might be tricky.
In your js function:
function counter(id){
const xhttp = new XMLHttpRequest();
xhttp.open("GET", `/getCounterOfUser/${id}`);
xhttp.addEventListener('load', function (event) {
if (event.target.responseText && event.target.status == 200) {
return parseInt(JSON.parse(event.target.responseText));
} else {
return 0;
}
});
xhttp.addEventListener(' error', function (event) {
// Define what happens in case of error
});
xhttp.send();
}
And you need to create new route:
Route::get('/getCounterOfUser/{id}', [App\Http\Controllers\Your_Controller::class, 'counter'])
Also you need to return JSON in your controller's function:
public function counter($id)
{
$toSearch = $id * 10000;
$latest = User::where('counter', '>=', $toSearch)->get()->last();
$res = $latest->counter % $toSearch;
return response()->json($res);
}
I have an android application I developed, that allows the sign up of users. I wrote a firebase cloud function that triggers when a User is created, to generate a 5-digit random integer value for the user who just signed up and it stores the generated code in firebase real time database in the following structure.
MainProject
|
|-Codes
|-UniqueUID_1
|-code:72834
|-UniqueUID_2
|-code:23784
The function that I deployed in order to make sure that the code generation is in the backend, is as seen below. There is a value "checker" which is initialised as 0. I use this value to determine when to exit the while loop. Basically I want the function to generate a 5-digit random value, then check the real time database if that generated value exists in all entries under "Codes", then if it does not exist, append it to the Codes under the relevant UID. If it exists, checker remains zero and the loop continues.
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var checker = 0;
exports.createUserCode = functions.auth.user().onCreate(event => {
while (checker == 0){
var newRand = getUserCode(89999,10000);
var userObject = {
uCode : newRand
};
//run a db query to strategically check value generated
return admin.database().ref("Codes/").orderByChild("uCode").equalTo(newRand).once("value",snapshot => {
if (!snapshot.exists()){
checker = 1;
//add uCode into respective uid slot under Codes
console.log(""+newRand+" : "+event.uid);
return admin.database().ref('Codes/' + event.uid).set(userObject);
}else{
checker = 0;
console.log("uCode "+newRand+" exists");
console.log("uCode generation failed for: "+event.uid);
}
});
}
});
function getUserCode(size, add){
return Math.floor(Math.random()*size+add);
}
I tested it and it worked fine. I thought the problem was solved. However, on the 7th to 11th trial, it gave me a Function returned undefined, expected Promise or value error. I tried it again after a while, and it generated the code fine. Some one else tested it and it brought the same error.
How can I fix this issue to ensure it always works? Thanks in advance.
It's really not clear to me what this function is supposed to do, and the top-level while loop doesn't make sense to me. However, I can see there are a few things wrong with what this code is doing.
First of all, it's depending on the global state checker too heavily. This value will not be the consistent for all function invocations, because they all won't be running on the same server instance. Each running server instance will see a different value of checker. Please watch this video series for more information about how Cloud Functions runs code.
Second of all, when checker has a value of 1 when the function starts, the function will do exactly what the error message says - it will return undefined. It should be pretty easy to see how this happens by reading the code.
To fix this, I suggest first coming up with a clear description of what this function is supposed to do when invoked. Also, I would strongly suggest eliminating dependency on global variables, unless you are absolutely certain you understand what you're doing and the effect they have.
I had the same problem a while ago. ESLint won't allow the function to complete because it evaluates whether every part of your code returns a promise.
From what i can see the first part of the if does return something. Try returning a boolean in the else block.
if (!snapshot.exists()){
checker = 1;
//add uCode into respective uid slot under Codes
console.log(""+newRand+" : "+event.uid);
return admin.database().ref('Codes/' + event.uid).set(userObject);
}else{
checker = 0;
console.log("uCode "+newRand+" exists");
console.log("uCode generation failed for: "+event.uid);
return false;
}
I am a beginner and using $.get to retrieve data from a rest API such as:
[{"id":"1","url":"http:\/\/123.456.78.910\/workforce\/images\/item1.jpg","price":"99","description":"Mobile Phone"},
{"id":"2","url":"http:\/\/123.456.78.910\/workforce\/images\/item2.jpg","price":"98","description":"Laptop"}
{"id":"3","url":"http:\/\/123.456.78.910\/workforce\/images\/item3.jpg","price":"92","description":"Console"}] }
$.get('http://xxxxxxxxxxx,
function (data) {
var obj = $.parseJSON(data);
So from what I understand I have retrieved the data from the REST API and parsed it so it is stored in a variable called obj.
My question is, how do I access and use each unique record in the obj variable?
Each record has it's own picture (item1.jpg, item2.jpg etc).
Whem my app loads I want it to show the item1.jpg image, and I want to be able to navigate to the other item pictures using buttons (previous / next).
I also want the description and price to be displayed underneath in some text input fields.
What I have figured so far is that I should:
Iterate through the obj variable, and store each record into an array.
Upon app initialisation I can set the default value for the image placeholder to array[index0].url, and set the description and price fields.
I can then set the previous and next buttons to array[currentIndex-1] or array[currentIndex+1].
Would this be the best way to do it?
Or can I just do this without using an array and manipulate the obj.data directly?
Thanks!!!
I may not be understanding what exactly what you want to do but I think I have the gist. If you just want to show the picture then the array of just images probably wouldn't be a bad idea. However, it looks like the Jason you're getting is already in an array. You can just use array index notation to get to what you want.
ie)
var arr = //your json response ;
var current = 0; //sets currently displayed object to the first in the array
var setCurrent = function () {
var image = arr[current]["url"];
}
You can then modify current however you want (on click on arrow iterate up/down, etc) then call the setCurrent function to set your image the the one you want. Hope that helps!
You can use the response you have from $.get() directly.
It is an array of objects.
You can use it like this:
console.log(data[2].description);
// outputs: "Console"
I've made a CodePen demo where it has a 4th object with a real image url to show you how to use the url info...
EDIT
Just in case you wouldn't know this:
You can use the response inside the scope of the $.get() callback...
You can not use it straith after the $.get() outside the callback since $.get() is asynchronous.
You can use it in some other handler wich will happen after the response is received.
var getResponse;
$.get('http://xxxxxxxxxxx', function (data) {
getResponse = data;
console.log(data[2].description);
// outputs: "Console"
console.log(getResponse[2].description);
// outputs: "Console"
});
console.log(getResponse[2].description);
// outputs: "Undefined"
// But since this handler will be triggered long after the response is obtained:
$("#somebutton").click(function(){
console.log(getResponse[2].description);
// outputs: "console"
});
In order for your page javascript to be able to access the data retrieved from your ajax request, you'll need to assign it to some variable which exists outside the callback function.
You will need to wait until the ajax request has been processed before you can read the array. So you might want to set the actual default image to be something that doesn't rely on the ajax request (a local image).
Here's a simple approach
// fake testing ajax func
function fakeget (url, callback) {
setTimeout(callback(JSON.stringify([
{"id":"1","url":"http:\/\/123.456.78.910\/workforce\/images\/item1.jpg","price":"99","description":"Mobile Phone"}, {"id":"2","url":"http:\/\/123.456.78.910\/workforce\/images\/item2.jpg","price":"98","description":"Laptop"},
{"id":"3","url":"http:\/\/123.456.78.910\/workforce\/images\/item3.jpg","price":"92","description":"Console"}
])), 1000);
}
// real code starts here
// global variables for ajax callback and setImg func to update
var imageData, currentImg;
// change this back to $.get for real
fakeget('http://xxxxxxxxxxx',
function (data) {
imageData = $.parseJSON(data);
setImg(0);
}
);
function setImg(index) {
// turns negative indices into expected "wraparound" index
currentImg = (index % imageData.length + imageData.length) % imageData.length;
var r = imageData[currentImg];
$("#theImg").attr('src', r.url);
$('#theDescription').text(r.price + " " + r.description);
}
$("#prev").click(function () {
setImg(currentImg - 1);
});
$("#next").click(function () {
setImg(currentImg + 1);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<img id='theImg' src='somedefault.jpg'>
<div id='theDescription'></div>
</div>
<button id='prev'>Prev</button>
<button id='next'>Next</button>
Few observations :
Your JSON Object is not a valid JSON.
No need to parse it again your data is already a JSON Object.
Working fiddle
var data = [{"id":"1","url":"http:\/\/123.456.78.910\/workforce\/images\/item1.jpg","price":"99","description":"Mobile Phone"},{"id":"2","url":"http:\/\/123.456.78.910\/workforce\/images\/item2.jpg","price":"98","description":"Laptop"}, {"id":"3","url":"http:\/\/123.456.78.910\/workforce\/images\/item3.jpg","price":"92","description":"Console"}];
for (var i in data) {
var imgUrl = data[i].url;
console.log(imgUrl);
}
I am using algolia javascript api for retrieving all records in my index using browse function, but still it is returning 1000 records. Here is my code:
function load_location_list(){
var client = algoliasearch('ID', 'KEY');
var index_name = "locations_new";
var attribute_list = "*";
var index = client.initIndex(index_name);
index.browse({
"attributesToRetrieve": attribute_list,
}).then(function search_Success(response) {
console.log(response);
});
}
Actually, browse doesn't return more than 1000 elements at the first call. However, the response contains a cursor that you can use to access the next elements with the browseFrom function.
However, the previous method is kind of manual. You probably want to use the browseAll function instead which lets you access all the elements sequentially.
You can find more informations about all the browse* functions in the README of the JS client (also available in the Algolia documentation).
I am trying to create a webapp on a node/couchdb/windows stack but get terribly stung by what seems to be a lack of experience.
In the database, there is a view that returns all users with passwords. Based on the tutorial for a blog I have tried to access the view through my node code.
Whenever I investigate the structure of the users or users variable, I get an undefined object.
The call to getDatabase() has been tested elsewhere and works at least for creating new documents.
function GetUser(login)
{
var users = GetUsers();
return users[login];
}
function GetUsers() {
var db = getDatabase();
var usersByEmail = [];
db.view("accounts", "password_by_email")
.then(function (resp) {
resp.rows.forEach(function (x) { usersByEmail[x.key] = x.value});
});
//usersByEmail['test'] = 'test';
return usersByEmail;
}
I am aware that both the use of non-hashed passwords as well as reading all users from the database is prohibitive in the final product - just in case anyone wanted to comment on that.
In case something is wrong with the way I access the view: I am using a design document called '_design/accounts' with the view name 'password_by_email'.
Your call to db.view is asynchronous, so when you hit return usersByEmail the object hasn't yet been populated. You simply can't return values from async code; you need to have it make a callback that will execute the code that relies on the result.