Issue trying to preform a delete with php and angular - javascript

I am trying to preform a delete with angular and php. I am pretty sure that my php is right.
But i am not able to delete. In my console log it says that my deletion was succesfull but when looking in the table I still see the recored.
Upon further inspection with debugger in chrome I see dat my parameter index is undefined -> http://gyazo.com/88b6dcf9d4c03a1fc9dd235303b20a8f
(part of) My HTML code:
<md-button class="md-primary" ng-click="delete_task(task.id)">Delete</md-button>
(part of) My app.js file:
/** function to delete a task from list referencing php **/
$scope.delete_task = function(index) {
debugger;
$http.post('db.php?action=delete_task',
{
'task_index' : index
}
)
.success(function (data, status, headers, config) {
// here we also replace how to get the user
getTaskFunction(
/* success function */
function(data) {
$scope.taskInfo = data;
console.log("The taks have been reloaded" , $scope.taskInfo);
},
/* error function */
function()
{
alert("Server load failed");
}
);
console.log('Deletion was succesfull');
})
.error(function(data, status, headers, config) {
console.log("You were NOT succesfull in deleting a task");
}
);
(part of) My PHP code:
<?php
include('config.php');
switch($_GET['action']) {
case 'get_ProjectType_Info' :
get_ProjectType_Info();
break;
case 'add_task' :
add_task();
break;
case 'get_Location_Info' :
get_Location_Info();
break;
case 'get_Task_Info' :
get_Task_Info();
break;
case 'delete_task' :
delete_task();
break;
}
/** Function to delete a task **/
function delete_task() {
$data = json_decode(file_get_contents("php://input"));
$index = $data->task_index;
echo ($index);
//print_r($data);
$del = mysql_query("DELETE FROM tblTask WHERE id = ".$index);
if($del)
return true;
return false;
}
I am not sure how to proceed from this point on.

It should be better not use querystring variables together with post variables as you're doing. Create a complete object on javascript statement in order to have something like this:
{
'task_index' : index,
action: 'delete_task'
}
And then you should threat this object data inside you switcher.
It would be great if you adopt some practices that take the code cleaner and easier to understand.
First thing of all, you should test your delete_task method. To make it successfully I suggest you to get the variables calling file_get_contents("php://input")) into the switch and passing them as method parameters. Make it this way:
<?php
// ...
// Receive id you have already collected
function delete_task($task_id){
$del = mysql_query("DELETE FROM tblTask WHERE id = ".$task_id);
if($del) return true;
return false;
}
// test that method
function test_delete(){
$ret = delete_task(4); // test with valid and invalid ids
}
?>
Obviously this is not a beautiful way to test methods and you should consider using any test framework for unit tests. But it's important to build methods in a way that you can change parameters and observe its behavior. Once you are assured that this method (the more critic one in this scenery) is working, you can go down one level on stack and check if your switcher is working well. At this time you can test your endpoint using Postman for Chrome, as an example.

Related

passing a variable with get request to PHP

Goal: I am trying to populate a dropdown from a database table column... I need to pass a variable from the front-end to the PHP indicating which table to ping from, as it may change depending on user selection beforehand...
This is where I'm trying to pass my which variable in to use as
this indicator — but I am having a hard time, because I am trying to
do so within a $.get request? If I could get $which = $_GET['id']; to report/gather what I have in my jQuery with let which = $(frm).attr("id"); I should be good to go.
How else could I do this, I don't think I could nor think it would be
any good practice to try and wrap a post around my get or vica
versa? Or chain a post then a get - I just need the PHP to access
my jQuery which variable so it knows which table to query.
Below is my most recent attempt: jquery
$('#agent').click(function(){
let which = $(frm).attr("id");
console.log(which);
$.get('dlteopt', 'id='+which, function (response) { // attempt at id
console.log(response);
$.each(response,function(i,obj){
let dd_data="<option value="+obj+">"+obj+"</option>";
$(dd_data).appendTo('#agent');
console.log(obj);
});
});
});
And the PHP side:
$app->get('/dlteopt', function ($request, $response, $args) {
$which = $_GET['id'];
var_dump($which);
if ($which) {
var_dump($which);
$db = $this->db;
$repo = new coolDBclass($db);
$selectIt = $repo->byCol($which);
}
});
here is function byCol btw: (all should be fine if I can just pass the correct table variable)
public function byCol($which) {
var_dump($which);
if ($which == 'table_1'){
$sql = "SELECT table_1 FROM tab.cool";
} else if ($which == 'table_2'){
$sql = "SELECT table_2 FROM tab.awesome";
} else if ($which == 'table_3'){
$sql = "SELECT table_3 FROM tab.rad";
}
// ............/
the relevant markup:
<select name='agent' id='agent'><option>Placeholder</option></select>
If you're trying to use the second parameter of the $.get method to pass the data, it needs to be an object.
See the examples in the docs.
.get('dlteopt', {id: which }, function (response) {

Understanding JavaScript for TFS widget

I've been trying to modify the sample dashboard widget at this location
https://learn.microsoft.com/en-us/vsts/extend/develop/add-dashboard-widget?view=vsts#part-2-hello-world-with-vsts-rest-api
However, reluctantly have to admit I simply can't understand the structure required to extend it
Near the end, it uses "load: function" and returns the outputs of a REST API call, which I can consume however I want
However, I need to make more than one different REST call, and I simply cannot figure out how to get that info usable in my function
I modified the code so it starts like this:
VSS.require(["TFS/Dashboards/WidgetHelpers", "TFS/Work/RestClient","VSS/Service", "TFS/WorkItemTracking/RestClient" ],
I then created a handle for the other call I want to make like this:
var queryClient = VSS_Service.getCollectionClient(TFS_Wit_QueryAPI.WorkItemTrackingHttpClient);
var queryResults = queryClient.getQuery(projectId, "Shared Queries/My Bugs");
However, I cannot consume the contents of queryResults - I know it's working up to a point as if I put in an invalid URL it will error as it knows it can't access anything there. If the URL is correct, no matter what I've tried - even stringify just to see what comes back - I get 'undefined' or something similar (it's definitely a valid JavaScript object)
The key seems to be right at the end when you have "load: function" except that only allows one thing to be returned? The reason I know this is if I change the function that it returns to be the one I've written rather than the one from the sample, it works fine - but the problem remains the same in that I can only process the results of one API call.
You can call more than one APIs, the code in that article is just the simple sample.
For Widget extension, you just need to return the status (e.g. Success()) in load function, so you can return status at the end of the function. For example:
var getQueryInfo = function (widgetSettings) {
// Get a WIT client to make REST calls to VSTS
return TFS_Wit_WebApi.getClient().getQuery(projectId, "Shared Queries/Feedback")
.then(function (query) {
// Create a list with query details
var $list = $('<ul>');
$list.append($('<li>').text("Query ID: " + query.id));
$list.append($('<li>').text("Query Name: " + query.name));
$list.append($('<li>').text("Created By: " + (query.createdBy ? query.createdBy.displayName: "<unknown>") ));
// Append the list to the query-info-container
var $container = $('#query-info-container');
$container.empty();
$container.append($list);
// Use the widget helper and return success as Widget Status
return true;
}, function (error) {
// Use the widget helper and return failure as Widget Status
console.log(error);
return false;
});
}
var getAnOhterQueryInfo = function (widgetSettings) {
// Get a WIT client to make REST calls to VSTS
return TFS_Wit_WebApi.getClient().getQuery(projectId, "Shared Queries/Bug")
.then(function (query) {
// Create a list with query details
var $list = $('<ul>');
$list.append($('<li>').text("Query ID: " + query.id));
$list.append($('<li>').text("Query Name: " + query.name));
$list.append($('<li>').text("Created By: " + (query.createdBy ? query.createdBy.displayName: "<unknown>") ));
// Append the list to the query-info-container
var $container = $('#query-info-container');
$container.empty();
$container.append($list);
// Use the widget helper and return success as Widget Status
return true;
}, function (error) {
// Use the widget helper and return failure as Widget Status
console.log(error);
return false;
});
}
return {
load: function (widgetSettings) {
// Set your title
var $title = $('h2.title');
$title.text('Hello World');
var r1= getQueryInfo(widgetSettings);
var r2=getAnOhterQueryInfo(widgetSettings);
if(r1==true && r2==true){
return WidgetHelpers.WidgetStatusHelper.Success();
}else{
return WidgetHelpers.WidgetStatusHelper.Failure("failed, check error in console");
}
}

Can't change Vue Instance data values

I'm building a custon social login page for my web application, and I'm stuck with a bug I can't find why it's hapenning .
Basically, I want to call a function called "connectFb" and then if all the Facebook API calls are successful, I would like to change a bunch of data in my vue instance in order to render other elements . (those are rendred conditionally via v-if)
Here's the part of my code responsible for this :
app = new Vue({
el : "#social-auth",
data: {
showTwitter : false,
showFb: true,
showPages: false,
fb_state: "unconnected",
continue_auth: false,
pages_fb: []
},
methods : {
connectFb: function() {
FB.login(function(response) {
if (response.authResponse) {
alert('You are logged in & cookie set!');
fb_token = response.authResponse.accessToken
FB.api('/me/accounts','get',{access_token: fb_token},function(pages){
if(pages["error"] !== undefined){
console.log('EROR')
}
else{
console.log("Got a list of pages");
console.log(pages);
this.pages_fb = pages.data;
this.showFb = false;
this.showPages = true;
this.continue_auth = true;
}
})
} else {
alert('User cancelled login or did not fully authorize.');
}
},{scope: 'public_profile,manage_pages'});
return false;
}
How The Code Works :
Basically, after the user is logged in to fb, it will get a list of his pages, this is not the problem, the problem is in the success callback after it (the callback related to the function fetching pages) . using the debugger I could see that the variable pages contains all the data I need and pages.data return an array of those pages info .
After this I'm trying to attribute it to my instance variable called pages_fb . when this code run pages_fb is always empty even though pages.data is not .
The problem is not only with pages_fb but also with all my instance variable that should change in the callback they are the same after the callback run .
I'm getting mad at this problem, so please help me understand what's wrong .
Extremely common mistake. this defined in your FB.login callback is not the Vue. Use an arrow function, closure, or bind to make it correct.
FB.api('/me/accounts','get',{access_token: fb_token}, pages => {
...
})
See How to access the correct this inside a callback?
When you use this. in a callback it isn't pointing to your Vue instance anymore. You can user => functions to bind this the way you want. Try this:
FB.api('/me/accounts','get',{access_token: fb_token},(pages) => {
if(pages["error"] !== undefined){
console.log('EROR')
}
else{
console.log("Got a list of pages");
console.log(pages);
this.pages_fb = pages.data;
this.showFb = false;
this.showPages = true;
this.continue_auth = true;
}
})

How do I use a php array within an array returned to Javascript?

I've been at this for more than half a day trying to figure out this problem and I swear I've tried every possible thing. So here's the idea behind what I'm trying to do... Every 10 seconds Javascript performs an AJAX call to see if you have any friends online, then returns a list of users, their status etc... Instead of formatting everything from PHP, I'll be formatting it from Javascript for various reasons... So here's what happens:
Javascript
// Let's get the data from the controller
$.post('/pagething', { datastuff }, function(data){
if(data.status == 'ok'){
// Magic nonsense here that can translate the array example:
var keys = Object.keys(data.allfriends);
}
} etc...
PHP
// Let's skip other code in the controller and focus on the important stuff
$friends_information = array(
'userid' => array();
'username' => array();
'avatar' => array();
'status' => array();
);
foreach($result_from_my_friends_model as $row){
// For ease of read, i'll just associate things with $row
$friends_information["userid"][] = $row->user_id;
$friends_information["username"][] = $row->username;
$friends_information["avatar"][] = $row->avatar;
$friends_information["status"][] = $row->status;
}
$result = array('status' => 'ok', 'allfriends' => $friends_information);
return json_encode($result);
exit();
The closest I've gotten is to either get the results by say username, or userid for example through a new object or getting the entire result but unable to distinguish between keys since object[0][1] for instance would return undefined.
Thank you in advanced, this stuff is tough to understand :/
There's no need to put each column into a separate element of $friend_array, things are generally easier if you keep all the data related to a particular friend together in an object. So do:
$result = array('status' => 'ok', 'allfriends' => $result_from_my_friends_model);
echo json_encode($result);
In the Javascript, make sure you specify that the result is JSON:
$.post('/pagething', { datastuff }, function(data) {
if (data.status == 'ok') {
$.each(data.allfriends, function(i, friend) {
// do stuff with friend.userid, friend.username, friend.avator, friend.status
});
}
}, 'json');
You already have your list_of_friend in your keysvariable of js. Just iterate through it then you will get your desired result. Best of luck

Inserting multiple values in Mysql using Nodejs and notifying user with a response

I am making a new webservice where i send a curl command with JSON and the JSON contains a array as
[{tempid:1,email:abc#123,address:asd},{tempid:2,email:abc#12345,address:asd45},{tempid:3,email:abc#1234,address:asd4}]
Now when i pass and insert the array in a mysql table tempid is just to show a mapping to the user to the contact id generated in the database as tempid:1 is now inserted and in database it has cid 120 , like this for tempid2 and 3 ,
But when i am trying to show the client the updated values it shows only one value , last last change not the whole updated Array. Its becuase of the async nature of the connection.querry function , so i need help in this , here is my webservice
contactadd webservice -->
for(var i=0;i<=request.body.contact.length-1;i++)
{
if(request.body.contact[i].tempid)
{ var ardata=new Array();
var o=request.body.contact[i];
pair=Object.keys(o).map(function(a){ return [a, o[a]] });
AM.addcontact(pair,request.session.user,request.body.contact.length,function(e,o){
if(!o)
{
response.send('something went wrong'+e);
}
else
{
//response.send(o);
}
});
}
}
Here is the update function in the database.js script -->
//ContactSync-addcontact module for database
exports.addcontact=function (arr,email,addnum,callback)
{
var counter=0;
var uid;
var data=new Array();
var showinsert=new Array();
var values=new Array();
var datatable=new Array();
var inserting=new Array();
var tempid=0;
connection.query('SELECT UID FROM user where email1="'+email.email+'"',function(err,rows,fields){
if(err)
{
throw err;
}
else
{
if(rows[0]!=undefined)
{
uid=rows[0]['UID'];
}
else
{
uid="no id in database";
}
}
});// get the UID of the inserting user
// make array of user provided data
for(var j=0;j<=arr.length-1;j++)
{
if(arr[j][0]!='tempid')
{
data.push(arr[j][0]);
}
else
{
tempid=arr[j][1];
}
}
connection.query('SELECT column_name FROM information_schema.columns where table_schema="webservice" AND table_name="usercontacts"',function(err,rows,fields){
if(err)
{
throw err;
}
else
{
for(var i=0;i<=rows.length-1;i++)
{
datatable.push(rows[i]['column_name']);
}
}
for(var k=0;k<=datatable.length-1;k++)
{
if(inArray(data[k],datatable))
{
inserting.push(data[k]);
}
}
if(inserting.length>0)
{
for(var z=0;z<=arr.length-1;z++)
{
if(inArray(arr[z][0],inserting))
{
values.push('"'+arr[z][1]+'"');
}
}
// Insert tempid values and data in the usercontacts table with inserting and values
connection.query('INSERT INTO usercontacts (cid,uid,'+inserting+') VALUES("","'+uid+'",'+values+')',function(err,rows,fields){
if(err)
{
throw err;
}
else
{
connection.query('SELECT * FROM usercontacts WHERE uid="'+uid+'" ORDER BY cid DESC LIMIT 0,'+addnum+'',function(err,rows,fields){
if(err)
{
throw err;
}
else
{ showinsert.push('temp-id: '+tempid+',cid:'+rows[0].cid+',uid:'+uid);
//for(var i=0;i<=inserting.length-1;i++)
forEach(inserting,function(row,index)
{
showinsert.push(inserting[index]+":"+values[index]);
counter+=1;
});
callback(null,showinsert);
}
});
}
});
//insertion finished
}
else
{
callback("Please Provide atleast one field to enter with tempid");
}
});
}
I just need to insert all the callback in a array which has been inserted and show user that array ,please help , completely stuck and then only i am trying StackOverflow.
Thank you for reading till the end BTW
I'm not sure what the specific problem is, but there are some problems with the code you've shared that will bite you sooner or later. One of these may be causing your problem.
Race conditions
If the query SELECT UID FROM user where email1= for any reason takes longer than the SELECT column_name FROM information_schema.columns just below it then you won't have a value for the variable uuid and your logic will fail. Remember that these calls are non-blocking, so you can't rely on one finishing before the other one unless they're nested or use another flow-control mechanism (As #Tracker points out, async is popular).
Catching edge cases
In the line below you're assigning a string value to the uid variable and then continuing to use that variable even though it now contains an error message.
uid="no id in database";
Doing that means that your code later on will have trouble reacting. Instead use a different variable, leave the uid = undefined or immediately return the callback with an error, e.g.
return callback(new Error("user not found"));
Reporting errors
Don't throw errors in Node unless you want to kill the process, e.g. dependency problems during server startup. It doesn't work like Java, async errors are not caught by try/catch and will kill your process or leave you in a state that's hard to reason about. Instead make the error object your first parameter to the callback and return it immediately, like this:
if ( err ) return callback(err);
Then in your client code you can always check the first parameter to see if there was a problem.
Security problem
As #Tracker mentioned, don't ever do the this:
connection.query('SELECT UID FROM user where email1="'+email.email+'"', ...
If the value of the variable is passed through as "; drop table user; or similar then you're in trouble. Instead you can use node-mysql's build in escaping like this:
connection.query('SELECT UID FROM user where email1=?', [email.email], ...
Whitelist
You're querying information_schema.columns in order to detect which fields are valid then inserting them into usercontacts. This is a clever trick, but increases a 3 query process to 4 queries, and raises questions if there are any fields that a user shouldn't be inserting data into. Using a column whitelist may seem like more code to maintain, but would actually be simpler than all the code required to match columns dynamically.
Arrays
I don't see the source for the function inArray() but it looks like it does the same as Array.prototype.indexOf() so it may be better to use that. e.g.
if ( datatable.indexOf(data[k]) > -1 ) inserting.push(data[k]);
Every line of custom code you can delete is a line of code you don't have to maintain.

Categories