2017-11-24 3 views
1

nodejsをバックエンドとしてログイン/登録アンドロイドアプリUIを作っています。私は登録ボタンをクリックするたびに、データベースに問い合わせる前にjsonレスポンスを送信します(ユーザー名が存在するかどうかを確認するSELECTステートメント)アンドロイド・アプリケーションに間違った応答が返され、正しいボタンを2回クリックすると応答。たとえば、データベースにtestというユーザ名があり、ユーザ名テストを使用してサインアップしようとすると、ユーザ名が既に取得されていることがわかります。消去テストと入力で 'bob'データベースにはまだユーザー名が入っていると言われていますが、登録ボタンを再度クリックするとユーザーが登録されます。私は非同期(これは、データベースのクエリ中またはクエリ前にjson応答を送信する)ため、これが起きていると仮定しています。どうすればこのシンクロナスを作ることができますか、これを解決する別の方法がありますか?NodeJSの機能を同期させますか?

サーバーファイル:

var express = require('express'); 
var app = express(); 
var bodyParser = require('body-parser'); 
var mysql = require('mysql'); 

//connection 
var con = mysql.createConnection({ 
    host: "localhost", 
    user: "root", 
    password: "password", 
    database : "androidtest" 
}); 

//use json 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: false })); 

//declare variables to hold values entered by the user 
var name; 
var username; 
var password; 
var age; 

//boolean array to let frontend know what is going on 
var response; 

app.post('/', function(req, res) { 
    //retrieve variables 
    username = req.body.username; 
    name = req.body.name; 
    age = req.body.age; 
    password = req.body.password; 

    //query database 
    //check if username is taken 
    var select = "SELECT * FROM users WHERE username = ? LIMIT 1"; 
    con.query(select, [username], function (err, results) { 
     if (err) throw err; 
     //if username is taken send json string 'exists' to android app 
     if(results.length) { 
      response = {"exists" : "true"};  
     //if username is available send string 'success' and add the user to the database 
     } else { 
      var add = "INSERT INTO users (name, username, age, password) VALUES (?, ?, ?, ?)"; 
      response = {"success" : "true"}; 
      con.query(add, [name, username, age, password]); 
      if (err) throw err; 
      console.log('row inserted'); 
     } 
    }); 
    //send json 
    res.json(response); 
    //prevents the functions from being executed more than once 
    res.end('/'); 
}); 
//listen on port 3000 
app.listen(3000); 

アンドロイドアプリのjava:あなたは次の行(の決算bracker後

res.json(...); 
res.end('/'); 

を配置する必要があり

bRegister.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View view) { 
     final String name = etName.getText().toString(); 
     final String username = etUserName.getText().toString(); 
     final String password = etPassword.getText().toString(); 
     final int age = Integer.parseInt(etAge.getText().toString()); 

     Response.Listener<String> responseListener = new Response.Listener<String>() { 
      @Override 
      public void onResponse(String response) { 
       try { 
        JSONObject jsonResponse = new JSONObject(response); 
        //Boolean exists = jsonResponse.getBoolean("exists"); 
        String exists = jsonResponse.getString("exists"); 
        if (exists.matches("true")) { 
         Toast toast = Toast.makeText(getApplicationContext(), "username already exists", Toast.LENGTH_SHORT); 
         toast.show(); 
        } 
       } catch(Exception e) { 
        e.printStackTrace(); 
       } 
       try { 
        JSONObject jsonResponse = new JSONObject(response); 
        //Boolean success = jsonResponse.getBoolean("success"); 
        String success = jsonResponse.getString("success"); 
        if (success.matches("true")) { 
         Intent intent = new Intent(RegisterActivity.this, LoginActivity.class); 
         RegisterActivity.this.startActivity(intent); 
        } else { 
         AlertDialog.Builder builder = new AlertDialog.Builder(RegisterActivity.this); 
         builder.setMessage("Register Failed") 
           .setNegativeButton("Retry", null) 
           .create() 
           .show(); 
        } 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
      } 
     }; 

     RegisterRequest registerRequest = new RegisterRequest(name, username, age, password, responseListener); 
     RequestQueue queue = Volley.newRequestQueue(RegisterActivity.this); 
     queue.add(registerRequest); 
    } 
}); 

}

+1

ここには数百の記事があります。 'res.json(...)'をデータベースコールバックの中に入れて、実際にデータを持っているときにだけトリガーするようにします。そして、 'res.json()'の後に 'res.end()'の必要はありません。 – jfriend00

+0

実際にはうまくいきましたが、私は質問をする前にそれを試みましたが、console.logを使用して検索された変数を表示していたので、複数回表示されていました。 end()は一度だけ表示され、データベースに追加されました。しかし、私はconsole.log()を使用していないし、複数回データベースに追加されているようには思われません – N00B

+0

私の答えはあなたを助けましたか?それは今働きますか? – cramopy

答えて

0

0123以降他のブロックの外側):クエリが完了したしたときに

console.log('row inserted'); 

それが最初に実行されます。

関連する問題