问:
Rails habtm grief am I dumb or rails bug? (desperate ; )
Greetings all,

I'm having a weird problem with a habtm relationship and honestly I'm beginning to think I may have stumbled upon some weird bug in rails 3.  Surely I'm crazy though.  I've been beating my head against the wall on this for 3 days, have googled everything under the sun I can think of and still can't come up with an answer.

Ok, the situation:

I'm creating a Rails app to replace both a Java app and a PHP app (java application and php front-end).  This is going to be a phased operation with the first phase being the Rails application takes over registration and billing.  In order to do this, the Rails application must create data in the databases for the Java and PHP apps.  The Rails application itself is using Devise for authentication.

In database.yml I have my standard 3 databases defined and also a connection defined for the Java apps database.

Here are pieces of the model definitions for the external object (I'm just creating regular rails models to talk to the external databases):

```<code>class Pushbroom::UserAccount < ActiveRecord::Base
  require 'digest/md5'
  require 'base64'

  establish_connection :pushbroom
  set_table_name :user_account
  set_primary_key :id

  has_and_belongs_to_many :user_roles, :join_table => 'pb_prod.users_roles', :class_name => 'Pushbroom::UserRole', :foreign_key => 'user_account_id', :association_foreign_key => 'user_role_id'
  belongs_to :user, :dependent => :destroy

  attr_accessible :user_roles, :admin_notes, :enabled, :username, :password_hash, :prefStore, :accepted_tos, :do_not_contact
end

class Pushbroom::UserRole < ActiveRecord::Base

  establish_connection :pushbroom
  set_table_name :user_role
  set_primary_key :id

  has_and_belongs_to_many :user_accounts, :join_table => 'pb_prod.users_roles', :class_name => 'Pushbroom::UserAccount', :foreign_key => 'user_role_id', :association_foreign_key => 'user_account_id'

end
</code>```

And finally my Rails application user object:

```<code>class User < ActiveRecord::Base

  after_create :send_welcome_email
  before_save :create_pushbroom_user_data

  # Include default devise modules. Others available are:
  # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  belongs_to :pb_user_account, :class_name => "Pushbroom::UserAccount", :foreign_key => "pb_user_account_id", :dependent => :destroy, :autosave => true

  # Setup accessible (or protected) attributes for your model
  attr_accessible :first_name, :last_name, :username, :dob, :email, :password,         :password_confirmation, :remember_me

  validates_presence_of :first_name, :last_name, :username, :dob
  validates_date :dob, :on_or_after => lambda { 100.years.ago }, :on_or_after_message => "must be on or after #{100.years.ago.strftime('%m-%d-%Y')}"
  validates_date :dob, :on_or_before => lambda { 13.years.ago }, :on_or_before_message => "must be on or before #{13.years.ago.strftime('%m-%d-%Y')}"

  def create_pushbroom_user_data
    pb_user = create_pushbroom_user
    pb_user_account = create_pushbroom_user_account(pb_user)
    pb_user_account.user_roles << Pushbroom::UserRole.find_by_name('user')
    self.pb_user_account = pb_user_account
  end

  def create_pushbroom_user
    pb_user = Pushbroom::User.new
    pb_user.attributes = self.attributes.slice(
      "email",
      "first_name",
      "last_name",
      "dob")

    pb_user
  end

def create_pushbroom_user_account(pb_user)
    pb_user_account = Pushbroom::UserAccount.new
    pb_user_account.enabled = true
    pb_user_account.password_hash =                 Pushbroom::UserAccount.create_password_digest(@plaintext_password, self.username)
    pb_user_account.username = self.username
    pb_user_account.user = pb_user

    pb_user_account
  end
</code>```

Seems like it should be pretty vanilla.  The ONLY weirdness here is that they aren't in the native rails database and one of the fields is named funny in the relations table.

So here's a rails console session where I create a rails user, call the method to create the external objects, then try to save:

```<code>ruby-1.9.2-p180 :001 > def user_fred
ruby-1.9.2-p180 :002?>       {
ruby-1.9.2-p180 :003 >             :first_name => "Fred",
ruby-1.9.2-p180 :004 >             :last_name => "Flinstone",
ruby-1.9.2-p180 :005 >             :username => "fflint",
ruby-1.9.2-p180 :006 >             :dob => "1986-06-01",
ruby-1.9.2-p180 :007 >             :email => "fred@mydomain.org",
ruby-1.9.2-p180 :008 >             :password => "badpass"
ruby-1.9.2-p180 :009?>         }
ruby-1.9.2-p180 :010?>     end
 => nil
ruby-1.9.2-p180 :011 > user = User.new(user_fred)
 => #<User id: nil, email: "fred@mydomain.org", encrypted_password:     "$2a$10$IiEOEoSnXIrP7VJAQYckfOVXuzm7Y5ZGo20ayLpSkHhz...", reset_password_token: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: nil, updated_at: nil, first_name: "Fred", last_name: "Flinstone", username: "fflint", dob: "1986-06-01", pb_user_account_id: nil>
ruby-1.9.2-p180 :012 > user.create_pushbroom_user_data
=> #<Pushbroom::UserAccount id: nil, created_by: nil, created_at: nil, updated_by: nil,     updated_at: nil, admin_notes: nil, enabled: true, username: "fflint", password_hash: "blah     blah", user_id: nil, prefStore: nil, accepted_tos: nil, do_not_contact: nil>
ruby-1.9.2-p180 :013 > user.pb_user_account.user_roles
 => [#<Pushbroom::UserRole id: 1, created_by: "script", created_at: "2008-11-10     12:10:44", updated_by: "script", updated_at: "2008-11-10 12:10:44", admin_notes: "", name:     "user", description: "Generic User Role", conditional: false>]
ruby-1.9.2-p180 :014 > user.save!
NoMethodError: undefined method `relation' for nil:NilClass
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activesupport-    3.0.5/lib/active_support/whiny_nil.rb:48:in `method_missing'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/arel-    2.0.9/lib/arel/insert_manager.rb:22:in `insert'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/arel-    2.0.9/lib/arel/crud.rb:26:in `insert'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-    3.0.5/lib/active_record/associations/has_and_belongs_to_many_association.rb:76:in     `insert_record'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-    3.0.5/lib/active_record/associations/association_proxy.rb:151:in `send'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/autosave_association.rb:306:in `block in     save_collection_association'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/associations/association_collection.rb:431:in `block in     method_missing'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/associations/association_proxy.rb:216:in `block in method_missing'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/associations/association_proxy.rb:216:in `each'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/associations/association_proxy.rb:216:in `method_missing'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/associations/association_collection.rb:431:in `method_missing'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/autosave_association.rb:297:in `save_collection_association'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/autosave_association.rb:163:in `block in add_autosave_association_callbacks'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activesupport-3.0.5/lib/active_support/callbacks.rb:415:in `_run_create_callbacks'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/callbacks.rb:281:in `create'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/persistence.rb:246:in `create_or_update'
... 18 levels...
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/callbacks.rb:277:in `create_or_update'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/persistence.rb:56:in `save!'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/validations.rb:49:in `save!'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/attribute_methods/dirty.rb:30:in `save!'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/transactions.rb:245:in `block in save!'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-    3.0.5/lib/active_record/transactions.rb:292:in `block in with_transaction_returning_status'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:139:in     `transaction'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/transactions.rb:207:in `transaction'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/transactions.rb:290:in `with_transaction_returning_status'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/transactions.rb:245:in `save!'
  from (irb):14
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/railties-3.0.5/lib/rails/commands/console.rb:44:in `start'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/railties-3.0.5/lib/rails/commands/console.rb:8:in `start'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/railties-3.0.5/lib/rails/commands.rb:23:in `<top (required)>'
  from script/rails:6:in `require'
  from script/rails:6:in `<main>'ruby-1.9.2-p180 :015 >
</code>```

If I remove the role assignment, everything is just peachy (finds, saves, destroys, etc), but the second I try to save roles everything blows sky-high with this message that, frankly, I don't get.  It knows its got the roles, there is no nil object that I can tell. . .and basically if I wasn't already bald I'd be pulling my hair out ; )

Any insight into this is EXTREMELY appreciated!

Gerald

P.S.  Also asked here http://railsforum.com/viewtopic.php?id=43647  Will duplicate answer if found.

答: Try doing some manual saves of the objects created in various places, such as the create_pushbroom_user_account(pb_user) method. I have had some issues in the past when relying on the "autosave" system.

Body:
Greetings all,

I'm having a weird problem with a habtm relationship and honestly I'm beginning to think I may have stumbled upon some weird bug in rails 3.  Surely I'm crazy though.  I've been beating my head against the wall on this for 3 days, have googled everything under the sun I can think of and still can't come up with an answer.

Ok, the situation:

I'm creating a Rails app to replace both a Java app and a PHP app (java application and php front-end).  This is going to be a phased operation with the first phase being the Rails application takes over registration and billing.  In order to do this, the Rails application must create data in the databases for the Java and PHP apps.  The Rails application itself is using Devise for authentication.

In database.yml I have my standard 3 databases defined and also a connection defined for the Java apps database.

Here are pieces of the model definitions for the external object (I'm just creating regular rails models to talk to the external databases):

class Pushbroom::UserAccount < ActiveRecord::Base
  require 'digest/md5'
  require 'base64'

  establish_connection :pushbroom
  set_table_name :user_account
  set_primary_key :id

  has_and_belongs_to_many :user_roles, :join_table => 'pb_prod.users_roles', :class_name => 'Pushbroom::UserRole', :foreign_key => 'user_account_id', :association_foreign_key => 'user_role_id'
  belongs_to :user, :dependent => :destroy

  attr_accessible :user_roles, :admin_notes, :enabled, :username, :password_hash, :prefStore, :accepted_tos, :do_not_contact
end

class Pushbroom::UserRole < ActiveRecord::Base

  establish_connection :pushbroom
  set_table_name :user_role
  set_primary_key :id

  has_and_belongs_to_many :user_accounts, :join_table => 'pb_prod.users_roles', :class_name => 'Pushbroom::UserAccount', :foreign_key => 'user_role_id', :association_foreign_key => 'user_account_id'

end

And finally my Rails application user object:

class User < ActiveRecord::Base

  after_create :send_welcome_email
  before_save :create_pushbroom_user_data

  # Include default devise modules. Others available are:
  # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

  belongs_to :pb_user_account, :class_name => "Pushbroom::UserAccount", :foreign_key => "pb_user_account_id", :dependent => :destroy, :autosave => true

  # Setup accessible (or protected) attributes for your model
  attr_accessible :first_name, :last_name, :username, :dob, :email, :password,         :password_confirmation, :remember_me

  validates_presence_of :first_name, :last_name, :username, :dob
  validates_date :dob, :on_or_after => lambda { 100.years.ago }, :on_or_after_message => "must be on or after #{100.years.ago.strftime('%m-%d-%Y')}"
  validates_date :dob, :on_or_before => lambda { 13.years.ago }, :on_or_before_message => "must be on or before #{13.years.ago.strftime('%m-%d-%Y')}"

  def create_pushbroom_user_data
    pb_user = create_pushbroom_user
    pb_user_account = create_pushbroom_user_account(pb_user)
    pb_user_account.user_roles << Pushbroom::UserRole.find_by_name('user')
    self.pb_user_account = pb_user_account
  end

  def create_pushbroom_user
    pb_user = Pushbroom::User.new
    pb_user.attributes = self.attributes.slice(
      "email",
      "first_name",
      "last_name",
      "dob")

    pb_user
  end

def create_pushbroom_user_account(pb_user)
    pb_user_account = Pushbroom::UserAccount.new
    pb_user_account.enabled = true
    pb_user_account.password_hash =                 Pushbroom::UserAccount.create_password_digest(@plaintext_password, self.username)
    pb_user_account.username = self.username
    pb_user_account.user = pb_user

    pb_user_account
  end

Seems like it should be pretty vanilla.  The ONLY weirdness here is that they aren't in the native rails database and one of the fields is named funny in the relations table.

So here's a rails console session where I create a rails user, call the method to create the external objects, then try to save:

ruby-1.9.2-p180 :001 > def user_fred
ruby-1.9.2-p180 :002?>       {
ruby-1.9.2-p180 :003 >             :first_name => "Fred",
ruby-1.9.2-p180 :004 >             :last_name => "Flinstone",
ruby-1.9.2-p180 :005 >             :username => "fflint",
ruby-1.9.2-p180 :006 >             :dob => "1986-06-01",
ruby-1.9.2-p180 :007 >             :email => "fred@mydomain.org",
ruby-1.9.2-p180 :008 >             :password => "badpass"
ruby-1.9.2-p180 :009?>         }
ruby-1.9.2-p180 :010?>     end
 => nil
ruby-1.9.2-p180 :011 > user = User.new(user_fred)
 => #<User id: nil, email: "fred@mydomain.org", encrypted_password:     "$2a$10$IiEOEoSnXIrP7VJAQYckfOVXuzm7Y5ZGo20ayLpSkHhz...", reset_password_token: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: nil, updated_at: nil, first_name: "Fred", last_name: "Flinstone", username: "fflint", dob: "1986-06-01", pb_user_account_id: nil>
ruby-1.9.2-p180 :012 > user.create_pushbroom_user_data
=> #<Pushbroom::UserAccount id: nil, created_by: nil, created_at: nil, updated_by: nil,     updated_at: nil, admin_notes: nil, enabled: true, username: "fflint", password_hash: "blah     blah", user_id: nil, prefStore: nil, accepted_tos: nil, do_not_contact: nil>
ruby-1.9.2-p180 :013 > user.pb_user_account.user_roles
 => [#<Pushbroom::UserRole id: 1, created_by: "script", created_at: "2008-11-10     12:10:44", updated_by: "script", updated_at: "2008-11-10 12:10:44", admin_notes: "", name:     "user", description: "Generic User Role", conditional: false>]
ruby-1.9.2-p180 :014 > user.save!
NoMethodError: undefined method `relation' for nil:NilClass
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activesupport-    3.0.5/lib/active_support/whiny_nil.rb:48:in `method_missing'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/arel-    2.0.9/lib/arel/insert_manager.rb:22:in `insert'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/arel-    2.0.9/lib/arel/crud.rb:26:in `insert'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-    3.0.5/lib/active_record/associations/has_and_belongs_to_many_association.rb:76:in     `insert_record'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-    3.0.5/lib/active_record/associations/association_proxy.rb:151:in `send'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/autosave_association.rb:306:in `block in     save_collection_association'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/associations/association_collection.rb:431:in `block in     method_missing'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/associations/association_proxy.rb:216:in `block in method_missing'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/associations/association_proxy.rb:216:in `each'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/associations/association_proxy.rb:216:in `method_missing'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/associations/association_collection.rb:431:in `method_missing'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/autosave_association.rb:297:in `save_collection_association'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/autosave_association.rb:163:in `block in add_autosave_association_callbacks'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activesupport-3.0.5/lib/active_support/callbacks.rb:415:in `_run_create_callbacks'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/callbacks.rb:281:in `create'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/persistence.rb:246:in `create_or_update'
... 18 levels...
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/callbacks.rb:277:in `create_or_update'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/persistence.rb:56:in `save!'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/validations.rb:49:in `save!'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/attribute_methods/dirty.rb:30:in `save!'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/transactions.rb:245:in `block in save!'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-    3.0.5/lib/active_record/transactions.rb:292:in `block in with_transaction_returning_status'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/connection_adapters/abstract/database_statements.rb:139:in     `transaction'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/transactions.rb:207:in `transaction'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/transactions.rb:290:in `with_transaction_returning_status'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/activerecord-3.0.5/lib/active_record/transactions.rb:245:in `save!'
  from (irb):14
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/railties-3.0.5/lib/rails/commands/console.rb:44:in `start'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/railties-3.0.5/lib/rails/commands/console.rb:8:in `start'
  from /Users/gander/.rvm/gems/ruby-1.9.2-p180@sms2/gems/railties-3.0.5/lib/rails/commands.rb:23:in `<top (required)>'
  from script/rails:6:in `require'
  from script/rails:6:in `'ruby-1.9.2-p180 :015 >

If I remove the role assignment, everything is just peachy (finds, saves, destroys, etc), but the second I try to save roles everything blows sky-high with this message that, frankly, I don't get.  It knows its got the roles, there is no nil object that I can tell. . .and basically if I wasn't already bald I'd be pulling my hair out ; )

Any insight into this is EXTREMELY appreciated!

Gerald

P.S.  Also asked here http://railsforum.com/viewtopic.php?id=43647  Will duplicate answer if found.


来源: stackexchange

问:
The variables I updated in my forEach, return to their original value
I am trying to query, that would get all of the earning and withdrawal amount and sum, but somehow after the forEach loop is done and exits, all of the updated values I placed in a variable return to their original values.</p>

```<code>  var withdrawbalance = 0;
  var totalearning = 0;

  userplans.forEach((up) => {
    DepositEarning.findOne({deposit: up.deposit._id})
      .then(depositearning => {
        withdrawbalance += parseInt(depositearning.WithdrawableBalance, 10);
      });
    Earning.findOne({deposit: up.deposit._id})
      .then(earnings => {
        totalearning += parseInt(earnings.Earning, 10);
    });
  })

  console.log(withdrawbalance);
  console.log(totalearning);
</code>```

答:
You are running asynchronous code inside the forEach and forEach will not wait until the asynchronous code finish, to do so, you must wrap your async code with a waiting primitive, like this

```<code>await Promise.all(userplans.map(async (up) => {
    await DepositEarning.findOne({deposit: up.deposit._id})
      .then(depositearning => {
        withdrawbalance += parseInt(depositearning.WithdrawableBalance, 10);
      });
    await Earning.findOne({deposit: up.deposit._id})
      .then(earnings => {
        totalearning += parseInt(earnings.Earning, 10);
    });
  }))
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I am trying to query, that would get all of the earning and withdrawal amount and sum, but somehow after the forEach loop is done and exits, all of the updated values I placed in a variable return to their original values.

  var withdrawbalance = 0;
  var totalearning = 0;

  userplans.forEach((up) => {
    DepositEarning.findOne({deposit: up.deposit._id})
      .then(depositearning => {
        withdrawbalance += parseInt(depositearning.WithdrawableBalance, 10);
      });
    Earning.findOne({deposit: up.deposit._id})
      .then(earnings => {
        totalearning += parseInt(earnings.Earning, 10);
    });
  })

  console.log(withdrawbalance);
  console.log(totalearning);

Body:
You are running asynchronous code inside the forEach and forEach will not wait until the asynchronous code finish, to do so, you must wrap your async code with a waiting primitive, like this

await Promise.all(userplans.map(async (up) => {
    await DepositEarning.findOne({deposit: up.deposit._id})
      .then(depositearning => {
        withdrawbalance += parseInt(depositearning.WithdrawableBalance, 10);
      });
    await Earning.findOne({deposit: up.deposit._id})
      .then(earnings => {
        totalearning += parseInt(earnings.Earning, 10);
    });
  }))


问:
any way to associate constant with type in Rust?
I want to associate a constant defined in my trait, and use it in a generic function.

```<code>trait My {
    const C: usize;
}

fn f<T>() -> [i32; T::C] where T: My {
    unimplemented!();
}
</code>```

But rust can not handle this

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a2d51315ba58f92d0e29bdac32115a62

Is there any other way to get constant from type in generic function?

答:
You can use the generic_array crate - this doesn't let you use fixed-size Rust arrays, but you can express an array length as an associated type

trait My {
  type C: ArrayLength<i32>;
}
```

<p>And then refer to it with a trait bound</p>

<pre class="lang-rust prettyprint-override"><code>fn f<T>() -> GenericArray<i32, T::C> where T: My {
  ...
}
</code>```

You can then also get the constant value from the type with to_usize.

Body:
I want to associate a constant defined in my trait, and use it in a generic function.

trait My {
    const C: usize;
}

fn f<T>() -> [i32; T::C] where T: My {
    unimplemented!();
}

But rust can not handle this

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a2d51315ba58f92d0e29bdac32115a62

Is there any other way to get constant from type in generic function?

Body:
You can use the generic_array crate - this doesn't let you use fixed-size Rust arrays, but you can express an array length as an associated type

trait My {
  type C: ArrayLength<i32>;
}

And then refer to it with a trait bound

fn f<T>() -> GenericArray<i32, T::C> where T: My {
  ...
}

You can then also get the constant value from the type with to_usize.


问:
How to use latitude and longitude retrieved from a service and show them on map?
I have defined a service (i.e. LocationService ) which gives me users's current latitude and longitude as an intent extras to my_activity. Now , I want to use  them to show current location on map (using Google maps) . I passed these latlng in mMap.animateCamera and mMap.moveCamera methods but they are not showing any Marker or zoom in to the current location . Please tell me if I am doing anything wrong .

Code for the LocationService and my MainActivity is pasted below :

LocationServices.java

```<code>public class LocationServicesForLocationUpdates extends Service implements LocationListener,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener{

private static final String TAG = LocationServicesForLocationUpdates.class.getSimpleName();

public static final String ACTION_LOCATION_BROADCAST
        = LocationServicesForLocationUpdates.class.getName() + "LocationBroadcast";

public static final String EXTRA_LATITUDE = "extra_latitude";
public static final String EXTRA_LONGITUDE = "extra_longitude";

private GoogleApiClient mLocationClient;
private LocationRequest mLocationRequest = new LocationRequest();

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    mLocationClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();

    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    mLocationRequest.setInterval(5000);
    mLocationRequest.setFastestInterval(3000);

    mLocationClient.connect();

   // return super.onStartCommand(intent, flags, startId);

    return START_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

/*
 * LOCATION CALLBACKS
 */
@Override
public void onConnected(Bundle dataBundle) {
    if (ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED

            && ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.

        Log.d(TAG, "== Error On onConnected() Permission not granted");
        //Permission not granted by user so cancel the further execution.

        return;
    }
    LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, mLocationRequest ,this);

    Log.d(TAG, "Connected to Google API");
}

//to get the location change
@Override
public void onLocationChanged(Location location) {
    Log.d(TAG, "Location changed");

    if (location != null) {
        Log.d(TAG, "== location != null");

        //Send result to activities
        sendMessageToUI(String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()));

    }
}

private void sendMessageToUI(String lat, String lng) {

    Log.d(TAG, "Sending info...");

    Intent intent = new Intent(ACTION_LOCATION_BROADCAST);
    intent.putExtra(EXTRA_LATITUDE, lat);
    intent.putExtra(EXTRA_LONGITUDE, lng);
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}
}
</code>```

New MainActivity.java

```<code> public class MainActivity extends AppCompatActivity implements OnMapReadyCallback{

private TextView mLatlngTxtVu , mAddressTxtVu;

private boolean mAlreadyStartedService;

private static final String TAG = ParentHomeActivity.class.getSimpleName();

private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;

private GoogleMap mGoogleMap;

Double mlattitude , mlongitude;

Marker mCurrentMarker;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_parent_home);

    Log.d(TAG, "onCreate: Called");
    mLatlngTxtVu = (TextView) findViewById(R.id.latlng_txtview);
    mAddressTxtVu = (TextView) findViewById(R.id.address_txtvu);

    LocalBroadcastManager.getInstance(this).registerReceiver(
            new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    mlattitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LATITUDE));
                    mlongitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LONGITUDE));

                    Log.d("latlng", "onReceive: " + mlongitude + mlattitude);

                    if (mlattitude != null && mlongitude != null) {
                        mLatlngTxtVu.setText("Latitude : " + mlattitude + "Longitude: " + mlongitude);
                    }
                }
            }, new IntentFilter(LocationServicesForLocationUpdates.ACTION_LOCATION_BROADCAST)
    );

    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.main_map);
    mapFragment.getMapAsync(MainActivity.this);

}

@Override
protected void onResume() {
    super.onResume();

    checkGooglePlayServices();

}

@Override
public void onMapReady(GoogleMap googleMap) {

    mGoogleMap = googleMap ;

    Log.d(TAG, "onMapReady: called");

    Log.d("coord", mlattitude + "   " + mlongitude);

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }

    mGoogleMap.setMyLocationEnabled(true);
    mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
    mGoogleMap.getUiSettings().setMapToolbarEnabled(false);

    CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(mlattitude, mlongitude))      // Sets the center of the map to location user
            .zoom(14)                   // Sets the zoom
            .bearing(0)                // Sets the orientation of the camera to east
            .tilt(90)                   // Sets the tilt of the camera to 30 degrees
            .build();                   // Creates a CameraPosition from the builder
    mGoogleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

    LatLng latLng = new LatLng(mlattitude  , mlongitude);

    mGoogleMap.addMarker(new MarkerOptions().position(latLng).title("YOU"));

   // mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));

   /* CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(mlattitude, mlongitude))      // Sets the center of the map to location user
            .zoom(17)                   // Sets the zoom
            .bearing(90)                // Sets the orientation of the camera to east
            .tilt(40)                   // Sets the tilt of the camera to 30 degrees
            .build();                   // Creates a CameraPosition from the builder
    mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));*/

}

private void checkGooglePlayServices() {

    //Check whether this user has installed Google play service which is being used by Location updates.
    if (isGooglePlayServicesAvailable()) {

        //Passing null to indicate that it is executing for the first time.
        checkAndPromptForInternetConnection(null);

    } else {
        Toast.makeText(getApplicationContext(), "Play services Not Available", Toast.LENGTH_LONG).show();
    }

}

private boolean checkAndPromptForInternetConnection(DialogInterface dialog) {

    ConnectivityManager connectivityManager
            = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();

    if (activeNetworkInfo == null || !activeNetworkInfo.isConnected()) {
        promptInternetConnect();
        return false;
    }

    if (dialog != null) {
        dialog.dismiss();
    }

    //Yes there is active internet connection. Next check Location is granted by user or not.

    if (checkPermissions()) { //Yes permissions are granted by the user. Go to the next step.
        startedLocationServices();
    } else {  //No user has not granted the permissions yet. Request now.
        requestPermissions();
    }
    return true;
}

/**
 * Step 3: Start the Location Monitor Service
 */
private void startedLocationServices() {

    //And it will be keep running until you close the entire application from task manager.
    //This method will executed only once.

    if (!mAlreadyStartedService && mLatlngTxtVu != null) {

        mLatlngTxtVu.setText("Running ");

        //Start location sharing service to app server.........
        Intent intent = new Intent(this, LocationServicesForLocationUpdates.class);
        startService(intent);

        mAlreadyStartedService = true;
        //Ends................................................
    }
}
/**
 * Show A Dialog with button to refresh the internet state.
 */
private void promptInternetConnect() {
    AlertDialog.Builder builder = new AlertDialog.Builder(ParentHomeActivity.this);
    builder.setTitle("No internet connection");
    builder.setMessage("Please Check your internet connection");

    String positiveText = "Refresh";
    builder.setPositiveButton(positiveText,
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {

                    //Block the Application Execution until user grants the permissions
                    if (checkAndPromptForInternetConnection(dialog)) {

                        //Now make sure about location permission.
                        if (checkPermissions()) {

                            //Step 2: Start the Location Monitor Service
                            //Everything is there to start the service.
                            startedLocationServices();
                        } else if (!checkPermissions()) {
                            requestPermissions();
                        }

                    }
                }
            });

    AlertDialog dialog = builder.create();
    dialog.show();
}

/**
 * Return the availability of GooglePlayServices
 */
public boolean isGooglePlayServicesAvailable() {
    GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
    int status = googleApiAvailability.isGooglePlayServicesAvailable(this);
    if (status != ConnectionResult.SUCCESS) {
        if (googleApiAvailability.isUserResolvableError(status)) {
            googleApiAvailability.getErrorDialog(this, status, 2404).show();
        }
        return false;
    }
    return true;
}

/**
 * Return the current state of the permissions needed.
 */
private boolean checkPermissions() {
    int permissionState1 = ActivityCompat.checkSelfPermission(this,
            android.Manifest.permission.ACCESS_FINE_LOCATION);

    int permissionState2 = ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_COARSE_LOCATION);

    return permissionState1 == PackageManager.PERMISSION_GRANTED && permissionState2 == PackageManager.PERMISSION_GRANTED;

}

/**
 * Start permissions requests.
 */
private void requestPermissions() {

    boolean shouldProvideRationale =
            ActivityCompat.shouldShowRequestPermissionRationale(this,
                    android.Manifest.permission.ACCESS_FINE_LOCATION);

    boolean shouldProvideRationale2 =
            ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION);

    // Provide an additional rationale to the img_user. This would happen if the img_user denied the
    // request previously, but didn't check the "Don't ask again" checkbox.
    if (shouldProvideRationale || shouldProvideRationale2) {
        Log.i(TAG, "Displaying permission rationale to provide additional context.");
        showSnackbar(R.string.grantPermission,
                android.R.string.ok, new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // Request permission
                        ActivityCompat.requestPermissions(ParentHomeActivity.this,
                                new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                                REQUEST_PERMISSIONS_REQUEST_CODE);
                    }
                });
    } else {
        Log.i(TAG, "Requesting permission");
        // Request permission. It's possible this can be auto answered if device policy
        // sets the permission in a given state or the img_user denied the permission
        // previously and checked "Never ask again".
        ActivityCompat.requestPermissions(ParentHomeActivity.this,
                new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                REQUEST_PERMISSIONS_REQUEST_CODE);
    }
}

/**
 * Shows a {@link Snackbar}.
 *
 * @param mainTextStringId The id for the string resource for the Snackbar text.
 * @param actionStringId   The text of the action item.
 * @param listener         The listener associated with the Snackbar action.
 */
private void showSnackbar(final int mainTextStringId, final int actionStringId,
                          View.OnClickListener listener) {
    Snackbar.make(
            findViewById(android.R.id.content),
            getString(mainTextStringId),
            Snackbar.LENGTH_INDEFINITE)
            .setAction(getString(actionStringId), listener).show();
}

/**
 * Callback received when a permissions request has been completed.
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    Log.i(TAG, "onRequestPermissionResult");
    if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
        if (grantResults.length <= 0) {
            // If img_user interaction was interrupted, the permission request is cancelled and you
            // receive empty arrays.
            Log.i(TAG, "User interaction was cancelled.");
        } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            Log.i(TAG, "Permission granted, updates requested, starting location updates");
            startedLocationServices();

        } else {
            // Permission denied.

            // Notify the img_user via a SnackBar that they have rejected a core permission for the
            // app, which makes the Activity useless. In a real app, core permissions would
            // typically be best requested during a welcome-screen flow.

            // Additionally, it is important to remember that a permission might have been
            // rejected without asking the img_user for permission (device policy or "Never ask
            // again" prompts). Therefore, a img_user interface affordance is typically implemented
            // when permissions are denied. Otherwise, your app could appear unresponsive to
            // touches or interactions which have required permissions.
            showSnackbar(R.string.permissionDenied,
                R.string.settings, new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // Build intent that displays the App settings screen.
                        Intent intent = new Intent();
                        intent.setAction(
                                Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                        Uri uri = Uri.fromParts("package",
                                BuildConfig.APPLICATION_ID, null);
                        intent.setData(uri);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);
                    }
                });
        }
    }
}

@Override
public void onDestroy() {

    //Stop location sharing service to app server.........

    stopService(new Intent(this, LocationServicesForLocationUpdates.class));
    mAlreadyStartedService = false;
    //Ends................................................

    super.onDestroy();
}

}
</code>```

Feel free to ask any queries in case you don't understand my problem and tell me the correct approach to solve my problem . I am new to android app development.

答:
in onMapReady() please create a new LatLng position and add it in as MarkerOption

```<code>   @Override
   public void onMapReady(GoogleMap googleMap) {
       .......
       .......
    // make sure you  are getting your latitude and longitude string value
    mlattitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LATITUDE));
    mlongitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LONGITUDE));

 CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(mLattitude,mlongitude)) // My position
            .zoom(14)           // Zoom Level
            .bearing(0)         // camera position, (0 north , 180 south )
            .tilt(90)           // Inclinaison de la camera
            .build();

    googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

LatLng position = new LatLng(mlattitude,mlongitude);
googleMap.addMarker(new MarkerOptions().position(position)
            .title("my marker"));
   }
</code>```

edit

Do not forget to call getMapAsync in your onReceive() method

```<code>    LocalBroadcastManager.getInstance(this).registerReceiver(
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                mlattitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LATITUDE));
                mlongitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LONGITUDE));

SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
        .findFragmentById(R.id.main_map);
mapFragment.getMapAsync(MainActivity.this);

                Log.d("latlng", "onReceive: " + mlongitude + mlattitude);
                if (mlattitude != null && mlongitude != null) {
                    mLatlngTxtVu.setText("Latitude : " + mlattitude + "Longitude: " + mlongitude);
                }
            }
        }, new IntentFilter(LocationServicesForLocationUpdates.ACTION_LOCATION_BROADCAST)
);

);
</code>```

Body:
I have defined a service (i.e. LocationService ) which gives me users's current latitude and longitude as an intent extras to my_activity. Now , I want to use  them to show current location on map (using Google maps) . I passed these latlng in mMap.animateCamera and mMap.moveCamera methods but they are not showing any Marker or zoom in to the current location . Please tell me if I am doing anything wrong .

Code for the LocationService and my MainActivity is pasted below :

LocationServices.java

public class LocationServicesForLocationUpdates extends Service implements LocationListener,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener{

private static final String TAG = LocationServicesForLocationUpdates.class.getSimpleName();

public static final String ACTION_LOCATION_BROADCAST
        = LocationServicesForLocationUpdates.class.getName() + "LocationBroadcast";

public static final String EXTRA_LATITUDE = "extra_latitude";
public static final String EXTRA_LONGITUDE = "extra_longitude";

private GoogleApiClient mLocationClient;
private LocationRequest mLocationRequest = new LocationRequest();

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    mLocationClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();

    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    mLocationRequest.setInterval(5000);
    mLocationRequest.setFastestInterval(3000);

    mLocationClient.connect();

   // return super.onStartCommand(intent, flags, startId);

    return START_STICKY;
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

/*
 * LOCATION CALLBACKS
 */
@Override
public void onConnected(Bundle dataBundle) {
    if (ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED

            && ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.

        Log.d(TAG, "== Error On onConnected() Permission not granted");
        //Permission not granted by user so cancel the further execution.

        return;
    }
    LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, mLocationRequest ,this);

    Log.d(TAG, "Connected to Google API");
}

//to get the location change
@Override
public void onLocationChanged(Location location) {
    Log.d(TAG, "Location changed");

    if (location != null) {
        Log.d(TAG, "== location != null");

        //Send result to activities
        sendMessageToUI(String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()));

    }
}

private void sendMessageToUI(String lat, String lng) {

    Log.d(TAG, "Sending info...");

    Intent intent = new Intent(ACTION_LOCATION_BROADCAST);
    intent.putExtra(EXTRA_LATITUDE, lat);
    intent.putExtra(EXTRA_LONGITUDE, lng);
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

}
}

New MainActivity.java

 public class MainActivity extends AppCompatActivity implements OnMapReadyCallback{

private TextView mLatlngTxtVu , mAddressTxtVu;

private boolean mAlreadyStartedService;

private static final String TAG = ParentHomeActivity.class.getSimpleName();

private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;

private GoogleMap mGoogleMap;

Double mlattitude , mlongitude;

Marker mCurrentMarker;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_parent_home);

    Log.d(TAG, "onCreate: Called");
    mLatlngTxtVu = (TextView) findViewById(R.id.latlng_txtview);
    mAddressTxtVu = (TextView) findViewById(R.id.address_txtvu);

    LocalBroadcastManager.getInstance(this).registerReceiver(
            new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    mlattitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LATITUDE));
                    mlongitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LONGITUDE));

                    Log.d("latlng", "onReceive: " + mlongitude + mlattitude);

                    if (mlattitude != null && mlongitude != null) {
                        mLatlngTxtVu.setText("Latitude : " + mlattitude + "Longitude: " + mlongitude);
                    }
                }
            }, new IntentFilter(LocationServicesForLocationUpdates.ACTION_LOCATION_BROADCAST)
    );

    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.main_map);
    mapFragment.getMapAsync(MainActivity.this);

}

@Override
protected void onResume() {
    super.onResume();

    checkGooglePlayServices();

}

@Override
public void onMapReady(GoogleMap googleMap) {

    mGoogleMap = googleMap ;

    Log.d(TAG, "onMapReady: called");

    Log.d("coord", mlattitude + "   " + mlongitude);

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }

    mGoogleMap.setMyLocationEnabled(true);
    mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
    mGoogleMap.getUiSettings().setMapToolbarEnabled(false);

    CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(mlattitude, mlongitude))      // Sets the center of the map to location user
            .zoom(14)                   // Sets the zoom
            .bearing(0)                // Sets the orientation of the camera to east
            .tilt(90)                   // Sets the tilt of the camera to 30 degrees
            .build();                   // Creates a CameraPosition from the builder
    mGoogleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

    LatLng latLng = new LatLng(mlattitude  , mlongitude);

    mGoogleMap.addMarker(new MarkerOptions().position(latLng).title("YOU"));

   // mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));

   /* CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(mlattitude, mlongitude))      // Sets the center of the map to location user
            .zoom(17)                   // Sets the zoom
            .bearing(90)                // Sets the orientation of the camera to east
            .tilt(40)                   // Sets the tilt of the camera to 30 degrees
            .build();                   // Creates a CameraPosition from the builder
    mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));*/

}

private void checkGooglePlayServices() {

    //Check whether this user has installed Google play service which is being used by Location updates.
    if (isGooglePlayServicesAvailable()) {

        //Passing null to indicate that it is executing for the first time.
        checkAndPromptForInternetConnection(null);

    } else {
        Toast.makeText(getApplicationContext(), "Play services Not Available", Toast.LENGTH_LONG).show();
    }

}

private boolean checkAndPromptForInternetConnection(DialogInterface dialog) {

    ConnectivityManager connectivityManager
            = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();

    if (activeNetworkInfo == null || !activeNetworkInfo.isConnected()) {
        promptInternetConnect();
        return false;
    }

    if (dialog != null) {
        dialog.dismiss();
    }

    //Yes there is active internet connection. Next check Location is granted by user or not.

    if (checkPermissions()) { //Yes permissions are granted by the user. Go to the next step.
        startedLocationServices();
    } else {  //No user has not granted the permissions yet. Request now.
        requestPermissions();
    }
    return true;
}

/**
 * Step 3: Start the Location Monitor Service
 */
private void startedLocationServices() {

    //And it will be keep running until you close the entire application from task manager.
    //This method will executed only once.

    if (!mAlreadyStartedService && mLatlngTxtVu != null) {

        mLatlngTxtVu.setText("Running ");

        //Start location sharing service to app server.........
        Intent intent = new Intent(this, LocationServicesForLocationUpdates.class);
        startService(intent);

        mAlreadyStartedService = true;
        //Ends................................................
    }
}
/**
 * Show A Dialog with button to refresh the internet state.
 */
private void promptInternetConnect() {
    AlertDialog.Builder builder = new AlertDialog.Builder(ParentHomeActivity.this);
    builder.setTitle("No internet connection");
    builder.setMessage("Please Check your internet connection");

    String positiveText = "Refresh";
    builder.setPositiveButton(positiveText,
            new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {

                    //Block the Application Execution until user grants the permissions
                    if (checkAndPromptForInternetConnection(dialog)) {

                        //Now make sure about location permission.
                        if (checkPermissions()) {

                            //Step 2: Start the Location Monitor Service
                            //Everything is there to start the service.
                            startedLocationServices();
                        } else if (!checkPermissions()) {
                            requestPermissions();
                        }

                    }
                }
            });

    AlertDialog dialog = builder.create();
    dialog.show();
}

/**
 * Return the availability of GooglePlayServices
 */
public boolean isGooglePlayServicesAvailable() {
    GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
    int status = googleApiAvailability.isGooglePlayServicesAvailable(this);
    if (status != ConnectionResult.SUCCESS) {
        if (googleApiAvailability.isUserResolvableError(status)) {
            googleApiAvailability.getErrorDialog(this, status, 2404).show();
        }
        return false;
    }
    return true;
}

/**
 * Return the current state of the permissions needed.
 */
private boolean checkPermissions() {
    int permissionState1 = ActivityCompat.checkSelfPermission(this,
            android.Manifest.permission.ACCESS_FINE_LOCATION);

    int permissionState2 = ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_COARSE_LOCATION);

    return permissionState1 == PackageManager.PERMISSION_GRANTED && permissionState2 == PackageManager.PERMISSION_GRANTED;

}

/**
 * Start permissions requests.
 */
private void requestPermissions() {

    boolean shouldProvideRationale =
            ActivityCompat.shouldShowRequestPermissionRationale(this,
                    android.Manifest.permission.ACCESS_FINE_LOCATION);

    boolean shouldProvideRationale2 =
            ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION);

    // Provide an additional rationale to the img_user. This would happen if the img_user denied the
    // request previously, but didn't check the "Don't ask again" checkbox.
    if (shouldProvideRationale || shouldProvideRationale2) {
        Log.i(TAG, "Displaying permission rationale to provide additional context.");
        showSnackbar(R.string.grantPermission,
                android.R.string.ok, new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // Request permission
                        ActivityCompat.requestPermissions(ParentHomeActivity.this,
                                new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                                REQUEST_PERMISSIONS_REQUEST_CODE);
                    }
                });
    } else {
        Log.i(TAG, "Requesting permission");
        // Request permission. It's possible this can be auto answered if device policy
        // sets the permission in a given state or the img_user denied the permission
        // previously and checked "Never ask again".
        ActivityCompat.requestPermissions(ParentHomeActivity.this,
                new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
                REQUEST_PERMISSIONS_REQUEST_CODE);
    }
}

/**
 * Shows a {@link Snackbar}.
 *
 * @param mainTextStringId The id for the string resource for the Snackbar text.
 * @param actionStringId   The text of the action item.
 * @param listener         The listener associated with the Snackbar action.
 */
private void showSnackbar(final int mainTextStringId, final int actionStringId,
                          View.OnClickListener listener) {
    Snackbar.make(
            findViewById(android.R.id.content),
            getString(mainTextStringId),
            Snackbar.LENGTH_INDEFINITE)
            .setAction(getString(actionStringId), listener).show();
}

/**
 * Callback received when a permissions request has been completed.
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    Log.i(TAG, "onRequestPermissionResult");
    if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
        if (grantResults.length <= 0) {
            // If img_user interaction was interrupted, the permission request is cancelled and you
            // receive empty arrays.
            Log.i(TAG, "User interaction was cancelled.");
        } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            Log.i(TAG, "Permission granted, updates requested, starting location updates");
            startedLocationServices();

        } else {
            // Permission denied.

            // Notify the img_user via a SnackBar that they have rejected a core permission for the
            // app, which makes the Activity useless. In a real app, core permissions would
            // typically be best requested during a welcome-screen flow.

            // Additionally, it is important to remember that a permission might have been
            // rejected without asking the img_user for permission (device policy or "Never ask
            // again" prompts). Therefore, a img_user interface affordance is typically implemented
            // when permissions are denied. Otherwise, your app could appear unresponsive to
            // touches or interactions which have required permissions.
            showSnackbar(R.string.permissionDenied,
                R.string.settings, new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // Build intent that displays the App settings screen.
                        Intent intent = new Intent();
                        intent.setAction(
                                Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                        Uri uri = Uri.fromParts("package",
                                BuildConfig.APPLICATION_ID, null);
                        intent.setData(uri);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);
                    }
                });
        }
    }
}

@Override
public void onDestroy() {

    //Stop location sharing service to app server.........

    stopService(new Intent(this, LocationServicesForLocationUpdates.class));
    mAlreadyStartedService = false;
    //Ends................................................

    super.onDestroy();
}

}

Feel free to ask any queries in case you don't understand my problem and tell me the correct approach to solve my problem . I am new to android app development.

Body:
in onMapReady() please create a new LatLng position and add it in as MarkerOption

   @Override
   public void onMapReady(GoogleMap googleMap) {
       .......
       .......
    // make sure you  are getting your latitude and longitude string value
    mlattitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LATITUDE));
    mlongitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LONGITUDE));

 CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(mLattitude,mlongitude)) // My position
            .zoom(14)           // Zoom Level
            .bearing(0)         // camera position, (0 north , 180 south )
            .tilt(90)           // Inclinaison de la camera
            .build();

    googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));

LatLng position = new LatLng(mlattitude,mlongitude);
googleMap.addMarker(new MarkerOptions().position(position)
            .title("my marker"));
   }

edit

Do not forget to call getMapAsync in your onReceive() method

    LocalBroadcastManager.getInstance(this).registerReceiver(
        new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                mlattitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LATITUDE));
                mlongitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LONGITUDE));

SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
        .findFragmentById(R.id.main_map);
mapFragment.getMapAsync(MainActivity.this);

                Log.d("latlng", "onReceive: " + mlongitude + mlattitude);
                if (mlattitude != null && mlongitude != null) {
                    mLatlngTxtVu.setText("Latitude : " + mlattitude + "Longitude: " + mlongitude);
                }
            }
        }, new IntentFilter(LocationServicesForLocationUpdates.ACTION_LOCATION_BROADCAST)
);

);


问:
How to optimize search algorithm
I have 4 dropdown multi-select filters in row.

Which need to render and on every selected option.
I need to add that selected option in new array and update that current array -> object.property.selected = false/true.

I am searching trough array of objects, and one property of every object have array of objects.

You can found code example on this code-pen: https://codepen.io/nikolatrajkovicits/pen/JqpWOX?editors=0012

Here is how that array looks:

```<code>export const getFiltersList = () => [
  {
    title: 'Taxonomy',
    options: [
      {
        id: 0,
        name: 'Competitions',
        selected: false,
        key: 'Taxonomy'
      },
      {
        id: 1,
        name: 'Events',
        selected: false,
        key: 'Taxonomy'
      },
      {
        id: 2,
        name: 'Data',
        selected: false,
        key: 'Taxonomy'
      },
      {
        id: 3,
        name: 'Organisations',
        selected: false,
        key: 'Taxonomy'
      },
      {
        id: 4,
        name: 'Players',
        selected: false,
        key: 'Taxonomy'
      },
      {
        id: 5,
        name: 'Teams',
        selected: false,
        key: 'Taxonomy'
      }
    ]
  },
  {
    title: 'Source',
    options: [
      {
        id: 0,
        name: 'Facebook',
        selected: false,
        key: 'Source'
      },
      {
        id: 1,
        name: 'Twitter',
        selected: false,
        key: 'Source'
      },
      {
        id: 2,
        name: 'Instagram',
        selected: false,
        key: 'Source'
      },
      {
        id: 3,
        name: 'Websites',
        selected: false,
        key: 'Source'
      }
    ]
  },
  {
    title: 'Timeframe',
    options: [
      {
        id: 0,
        name: 'Past hour',
        selected: false,
        key: 'Timeframe'
      },
      {
        id: 1,
        name: 'Past 24 hours',
        selected: false,
        key: 'Timeframe'
      },
      {
        id: 2,
        name: 'Past week',
        selected: false,
        key: 'Timeframe'
      },
      {
        id: 3,
        name: 'Past month',
        selected: false,
        key: 'Timeframe'
      },
      {
        id: 4,
        name: 'Past year',
        selected: false,
        key: 'Timeframe'
      }
    ]
  },
  {
    title: 'Location',
    options: [
      {
        id: 0,
        name: 'Location 1',
        selected: false,
        key: 'Location'
      },
      {
        id: 1,
        name: 'Location 2',
        selected: false,
        key: 'Location'
      },
      {
        id: 2,
        name: 'Location 3',
        selected: false,
        key: 'Location'
      },
      {
        id: 3,
        name: 'Location 4',
        selected: false,
        key: 'Location'
      }
    ]
  }
];

</code>```

Here is algorithm:

```<code>selectFilter = ({ id, key }) => {
    const { filtersList, selectedFilters } = this.state;
    const tempFilters = filtersList;
    const tempSelected = selectedFilters;
    const i = tempSelected.length;

    tempFilters.forEach((filter) => {
      if (filter.title === key) {
        filter.options.forEach((option) => {
          if (option.id === id) {
            option.selected = !option.selected;
            const isFilterExist = tempSelected.filter(
              (selectedFilter) => selectedFilter.name === option.name
            );
            if (!isFilterExist.length) {
              const selectedItem = { name: option.name, key, id };
              tempSelected[i] = selectedItem;
            }
          }
        });
      }
    });
    this.setState({
      filtersList: tempFilters,
      selectedFilters: tempSelected
    });
  };

</code>```

On code pen you can found version which is in pure javascript code.

How to make better cleaner faster search algo?

Any advice article, tutorial, comment?

答:
So I have a react implementation, as you tagged it.

In a nutshell, I took the two concerns (data & state) and split them out from your inbound data. In addition your data coming in had 2 properties which were unnecessary (selected & key).

key - This is react implementation that you add during the return function. I used your title as it was unique across each object.

selected - Data should contain the important properties coming into the app, this is classed as application state more than data. If you took this approach you would add more more computing overhead. You would have to update every other instance to  false when you select an item. I lifted this state up to the main app.

Here is the code I wrote:

dropdown-data.json:

```<code>[
  {
    "title": "Taxonomy",
    "options": [
      {
        "id": 0,
        "name": "Competitions"
      },
      {
        "id": 1,
        "name": "Events"
      },
      {
        "id": 2,
        "name": "Data"
      },
      {
        "id": 3,
        "name": "Organisations"
      },
      {
        "id": 4,
        "name": "Players"
      },
      {
        "id": 5,
        "name": "Teams"
      }
    ]
  },
  {
    "title": "Source",
    "options": [
      {
        "id": 0,
        "name": "Facebook"
      },
      {
        "id": 1,
        "name": "Twitter"
      },
      {
        "id": 2,
        "name": "Instagram"
      },
      {
        "id": 3,
        "name": "Websites"
      }
    ]
  },
  {
    "title": "Timeframe",
    "options": [
      {
        "id": 0,
        "name": "Past hour"
      },
      {
        "id": 1,
        "name": "Past 24 hours"
      },
      {
        "id": 2,
        "name": "Past week"
      },
      {
        "id": 3,
        "name": "Past month"
      },
      {
        "id": 4,
        "name": "Past year"
      }
    ]
  },
  {
    "title": "Location",
    "options": [
      {
        "id": 0,
        "name": "Location 1"
      },
      {
        "id": 1,
        "name": "Location 2"
      },
      {
        "id": 2,
        "name": "Location 3"
      },
      {
        "id": 3,
        "name": "Location 4"
      }
    ]
  }
]
</code>```

<App />:

```<code>import React from "react";

import dropdownData from "./dropdown-data.json";

const Dropdown = ({ options = [], ...props }) => (
  <select {...props}>
    {options.map(({ id, ...option }) => (
      <option key={id}>{option.name}</option>
    ))}
  </select>
);

const App = () => {
  const [data, setData] = React.useState({});

  return (
    <>
      {/* A debugging helper :) */}
      ```{JSON.stringify(data, null, 2)}```

      {dropdownData.map(({ title, options }) => (
        <Dropdown
          key={title}
          {...{ options }}
          onChange={({ target }) =>
            setData({
              ...data,
              [title.toLowerCase()]: target.value
            })
          }
        />
      ))}
    </>
  );
};

export default App;
</code>```

The pre tag shows the data being returned below. Since there was an empty object for the initial state, your state does not get populated with untouched / unneeded data.

Let me know how this helps, this was 2 files inside a create-react-app.

Title: How to optimize search algorithm

Body:
I have 4 dropdown multi-select filters in row.

Which need to render and on every selected option.
I need to add that selected option in new array and update that current array -> object.property.selected = false/true.

I am searching trough array of objects, and one property of every object have array of objects.

You can found code example on this code-pen: https://codepen.io/nikolatrajkovicits/pen/JqpWOX?editors=0012

Here is how that array looks:

export const getFiltersList = () => [
  {
    title: 'Taxonomy',
    options: [
      {
        id: 0,
        name: 'Competitions',
        selected: false,
        key: 'Taxonomy'
      },
      {
        id: 1,
        name: 'Events',
        selected: false,
        key: 'Taxonomy'
      },
      {
        id: 2,
        name: 'Data',
        selected: false,
        key: 'Taxonomy'
      },
      {
        id: 3,
        name: 'Organisations',
        selected: false,
        key: 'Taxonomy'
      },
      {
        id: 4,
        name: 'Players',
        selected: false,
        key: 'Taxonomy'
      },
      {
        id: 5,
        name: 'Teams',
        selected: false,
        key: 'Taxonomy'
      }
    ]
  },
  {
    title: 'Source',
    options: [
      {
        id: 0,
        name: 'Facebook',
        selected: false,
        key: 'Source'
      },
      {
        id: 1,
        name: 'Twitter',
        selected: false,
        key: 'Source'
      },
      {
        id: 2,
        name: 'Instagram',
        selected: false,
        key: 'Source'
      },
      {
        id: 3,
        name: 'Websites',
        selected: false,
        key: 'Source'
      }
    ]
  },
  {
    title: 'Timeframe',
    options: [
      {
        id: 0,
        name: 'Past hour',
        selected: false,
        key: 'Timeframe'
      },
      {
        id: 1,
        name: 'Past 24 hours',
        selected: false,
        key: 'Timeframe'
      },
      {
        id: 2,
        name: 'Past week',
        selected: false,
        key: 'Timeframe'
      },
      {
        id: 3,
        name: 'Past month',
        selected: false,
        key: 'Timeframe'
      },
      {
        id: 4,
        name: 'Past year',
        selected: false,
        key: 'Timeframe'
      }
    ]
  },
  {
    title: 'Location',
    options: [
      {
        id: 0,
        name: 'Location 1',
        selected: false,
        key: 'Location'
      },
      {
        id: 1,
        name: 'Location 2',
        selected: false,
        key: 'Location'
      },
      {
        id: 2,
        name: 'Location 3',
        selected: false,
        key: 'Location'
      },
      {
        id: 3,
        name: 'Location 4',
        selected: false,
        key: 'Location'
      }
    ]
  }
];

Here is algorithm:

selectFilter = ({ id, key }) => {
    const { filtersList, selectedFilters } = this.state;
    const tempFilters = filtersList;
    const tempSelected = selectedFilters;
    const i = tempSelected.length;

    tempFilters.forEach((filter) => {
      if (filter.title === key) {
        filter.options.forEach((option) => {
          if (option.id === id) {
            option.selected = !option.selected;
            const isFilterExist = tempSelected.filter(
              (selectedFilter) => selectedFilter.name === option.name
            );
            if (!isFilterExist.length) {
              const selectedItem = { name: option.name, key, id };
              tempSelected[i] = selectedItem;
            }
          }
        });
      }
    });
    this.setState({
      filtersList: tempFilters,
      selectedFilters: tempSelected
    });
  };

On code pen you can found version which is in pure javascript code.

How to make better cleaner faster search algo?

Any advice article, tutorial, comment?

Body:
So I have a react implementation, as you tagged it.

In a nutshell, I took the two concerns (data & state) and split them out from your inbound data. In addition your data coming in had 2 properties which were unnecessary (selected & key).

key - This is react implementation that you add during the return function. I used your title as it was unique across each object.

selected - Data should contain the important properties coming into the app, this is classed as application state more than data. If you took this approach you would add more more computing overhead. You would have to update every other instance to  false when you select an item. I lifted this state up to the main app.

Here is the code I wrote:

dropdown-data.json:

[
  {
    "title": "Taxonomy",
    "options": [
      {
        "id": 0,
        "name": "Competitions"
      },
      {
        "id": 1,
        "name": "Events"
      },
      {
        "id": 2,
        "name": "Data"
      },
      {
        "id": 3,
        "name": "Organisations"
      },
      {
        "id": 4,
        "name": "Players"
      },
      {
        "id": 5,
        "name": "Teams"
      }
    ]
  },
  {
    "title": "Source",
    "options": [
      {
        "id": 0,
        "name": "Facebook"
      },
      {
        "id": 1,
        "name": "Twitter"
      },
      {
        "id": 2,
        "name": "Instagram"
      },
      {
        "id": 3,
        "name": "Websites"
      }
    ]
  },
  {
    "title": "Timeframe",
    "options": [
      {
        "id": 0,
        "name": "Past hour"
      },
      {
        "id": 1,
        "name": "Past 24 hours"
      },
      {
        "id": 2,
        "name": "Past week"
      },
      {
        "id": 3,
        "name": "Past month"
      },
      {
        "id": 4,
        "name": "Past year"
      }
    ]
  },
  {
    "title": "Location",
    "options": [
      {
        "id": 0,
        "name": "Location 1"
      },
      {
        "id": 1,
        "name": "Location 2"
      },
      {
        "id": 2,
        "name": "Location 3"
      },
      {
        "id": 3,
        "name": "Location 4"
      }
    ]
  }
]

<App />:

import React from "react";

import dropdownData from "./dropdown-data.json";

const Dropdown = ({ options = [], ...props }) => (
  <select {...props}>
    {options.map(({ id, ...option }) => (
      <option key={id}>{option.name}</option>
    ))}
  </select>
);

const App = () => {
  const [data, setData] = React.useState({});

  return (
    <>
      {/* A debugging helper :) */}
      <pre>{JSON.stringify(data, null, 2)}</pre>

      {dropdownData.map(({ title, options }) => (
        <Dropdown
          key={title}
          {...{ options }}
          onChange={({ target }) =>
            setData({
              ...data,
              [title.toLowerCase()]: target.value
            })
          }
        />
      ))}
    </>
  );
};

export default App;

The pre tag shows the data being returned below. Since there was an empty object for the initial state, your state does not get populated with untouched / unneeded data.

Let me know how this helps, this was 2 files inside a create-react-app.


问:
Newbie question: What is the correct way to pass error message from ajax calls?
The theory says:
- if there is no error, return 200
- if there is an error, return 404
but how to pass error messages with the 404 code?

I have built a backend that currently returns code 200 AND in the json response there is a 'success' flag. If the flag is false, another field contains error message.
(There may be several reasons why the operation failed and I want to display the reason to the user).

I am aware that by convention the 404 error should be returned but how can I pass the error message in that case ???

答:
If their is no error return 200, if there is an error return corresponding error code and message not just 404. 404 is received when the data or resource expected is not found.

Take a look at HTTP Error Codes

You should set the value of error message field based on the error that is thrown. You can either catch any error and set it to error message or you can generate your own reasons for different kinds of errors.

Your response should look like

```<code>{
    'success': false,
    'errorCode' : 'code', //code returned by error
    'errorMessage' : 'Custom Message' //error message
}
</code>```

Note: Post some code by editing the question so others can help you a bit better.

Body:
If their is no error return 200, if there is an error return corresponding error code and message not just 404. 404 is received when the data or resource expected is not found.

Take a look at HTTP Error Codes

You should set the value of error message field based on the error that is thrown. You can either catch any error and set it to error message or you can generate your own reasons for different kinds of errors.

Your response should look like

{
    'success': false,
    'errorCode' : 'code', //code returned by error
    'errorMessage' : 'Custom Message' //error message
}

Note: Post some code by editing the question so others can help you a bit better.


问:
using distinct command
using distinct command in SQL is good practice or not? is there any drawback of distinct command?</p>

答:
From this http://www.mindfiresolutions.com/Think-Before-Using-Distinct-Command-Arbitarily-1050.php

Sometimes it is seen if the beginners are getting some duplicates in their resultset then they are using DISTINCT. But this has its own disadvantages.

Distinct decreases the query's performance. Because the normal procedure is sorting the results and then removing rows that
are equal to the row immediately before it.

DISTINCT compares between all fields of the record. So DISTINCT increases computation .

ContentLicense: CC BY-SA 3.0

Title: using distinct command


问:
NoClassDefFoundError after exporting jar
I am trying to work with MongoDB in my Java projects.

After exporting my project to a file I get a no class defined error for the MongoClient.

I get no errors while exporting.

I use Maven to import the different dependencies and all jars are being exported properly

import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;

public class MongoDB {

    private static MongoClient client;

    public static void init() {
        try {
            client = MongoClients.create("mongodb://localhost:27017/xenoncraft");
            System.out.println("[XenonSuite] Successfully connected to MongoDB");
        } catch(Exception e) {
            System.out.println("[XenonSuite] Following errors were catched while connecting to MongoDB");
            e.printStackTrace();
        }
    }
```

答:
Ensure that, you have the following dependency in Maven pom.xml.

    org.mongodb
    mongodb-driver
    3.9.1

If you are not using maven, you have to download this jar file from mvnrepository.com and also you have to download bson.jar, mongodb-driver-core with the version 3.9.1 and you have to download slf4j-api.jar with version 1.7.6.


问:
I'm trying to make an API in python that receives data in JSON
I'm trying to make an API which depending on which store the user likes and what specific item they like it will retrieve the data in JSON, for example, in Tesco search for Nutella, it works perfectly to find when I do it for just 1 store but when I did it for more than 1 it get errors.

I've tried a for loop and if loop, I've gotten better results
from bs4 import BeautifulSoup libraries to do this.

My code:

```<code>import requests
from bs4 import BeautifulSoup

num = int(input('''press 1 for tesco
press 2 for morrisions
press 3 for sainsbury's
'''))

print("please enter the food you want to search for: ")
flag = num%2
txt = input("")

if flag == 1:
    tesco_url = requests.get('https://www.tesco.com/groceries/en-GB/search?query=' + txt).text
elif flag == 2:
    morrisons_url = requests.get('https://groceries.morrisons.com/search?entry=' + txt).text
elif flag == 3:
    sainsburys_url = requests.get('https://www.sainsburys.co.uk/webapp/wcs/stores/servlet/SearchDisplayView?catalogId=10123&langId=44&storeId=10151&krypto=OYaxfyCjgnRApUa%2FS%2BjRmgHslGfDEUtd3xECMndoz2f9gvq5KRuP8TuhW4m1jnUT%2FJU3fBivUiAIozuhmBLJJJQe6gcTedPJTASuwsZfLkt49e%2FYAPxDyWxCjeiyFxNN5WjSEdcW7LMdmfJbn3TmGVBZKVIxqu1zUw7IT8Qo2afgUyuCpJPcxPbmc2gWJMpi#langId=44&storeId=10151&catalogId=10123&categoryId=&parent_category_rn=&top_category=&pageSize=60&orderBy=RELEVANCE&searchTerm=' + txt).text

soup = BeautifulSoup(flag, 'lxml')
print(soup.prettify())
</code>```

The error I'm getting:

```<code>Traceback (most recent call last):
  File "My API.py", line 23, in <module>
    soup = BeautifulSoup(flag, 'lxml')
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/bs4/__init__.py", line 245, in __init__
    elif len(markup) <= 256 and (
TypeError: object of type 'int' has no len()
</code>```

答:
BeautifulSoup requires XML, which you probably forgot to update when adding more stores. Also I'm not sure why you have flag = num%2, as flag will then only be values [0, 1]. If you replace flag with num, it should work as expected.

```<code>import requests
from bs4 import BeautifulSoup

num = int(input('''press 1 for tesco
press 2 for morrisions
press 3 for sainsbury's
'''))

print("please enter the food you want to search for: ")
flag = num                   # <--- notice this
txt = input("")

if flag == 1:
    markup = requests.get('https://www.tesco.com/groceries/en-GB/search?query=' + txt).text
elif flag == 2:
    markup = requests.get('https://groceries.morrisons.com/search?entry=' + txt).text
elif flag == 3:
    markup = requests.get('https://www.sainsburys.co.uk/webapp/wcs/stores/servlet/SearchDisplayView?catalogId=10123&langId=44&storeId=10151&krypto=OYaxfyCjgnRApUa%2FS%2BjRmgHslGfDEUtd3xECMndoz2f9gvq5KRuP8TuhW4m1jnUT%2FJU3fBivUiAIozuhmBLJJJQe6gcTedPJTASuwsZfLkt49e%2FYAPxDyWxCjeiyFxNN5WjSEdcW7LMdmfJbn3TmGVBZKVIxqu1zUw7IT8Qo2afgUyuCpJPcxPbmc2gWJMpi#langId=44&storeId=10151&catalogId=10123&categoryId=&parent_category_rn=&top_category=&pageSize=60&orderBy=RELEVANCE&searchTerm=' + txt).text

soup = BeautifulSoup(markup, 'lxml')
print(soup.prettify())
</code>```

Body:
I'm trying to make an API which depending on which store the user likes and what specific item they like it will retrieve the data in JSON, for example, in Tesco search for Nutella, it works perfectly to find when I do it for just 1 store but when I did it for more than 1 it get errors.

I've tried a for loop and if loop, I've gotten better results
from bs4 import BeautifulSoup libraries to do this.

My code:

import requests
from bs4 import BeautifulSoup

num = int(input('''press 1 for tesco
press 2 for morrisions
press 3 for sainsbury's
'''))

print("please enter the food you want to search for: ")
flag = num%2
txt = input("")

if flag == 1:
    tesco_url = requests.get('https://www.tesco.com/groceries/en-GB/search?query=' + txt).text
elif flag == 2:
    morrisons_url = requests.get('https://groceries.morrisons.com/search?entry=' + txt).text
elif flag == 3:
    sainsburys_url = requests.get('https://www.sainsburys.co.uk/webapp/wcs/stores/servlet/SearchDisplayView?catalogId=10123&langId=44&storeId=10151&krypto=OYaxfyCjgnRApUa%2FS%2BjRmgHslGfDEUtd3xECMndoz2f9gvq5KRuP8TuhW4m1jnUT%2FJU3fBivUiAIozuhmBLJJJQe6gcTedPJTASuwsZfLkt49e%2FYAPxDyWxCjeiyFxNN5WjSEdcW7LMdmfJbn3TmGVBZKVIxqu1zUw7IT8Qo2afgUyuCpJPcxPbmc2gWJMpi#langId=44&storeId=10151&catalogId=10123&categoryId=&parent_category_rn=&top_category=&pageSize=60&orderBy=RELEVANCE&searchTerm=' + txt).text

soup = BeautifulSoup(flag, 'lxml')
print(soup.prettify())

The error I'm getting:

Traceback (most recent call last):
  File "My API.py", line 23, in <module>
    soup = BeautifulSoup(flag, 'lxml')
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/bs4/__init__.py", line 245, in __init__
    elif len(markup) <= 256 and (
TypeError: object of type 'int' has no len()

Body:
BeautifulSoup requires XML, which you probably forgot to update when adding more stores. Also I'm not sure why you have flag = num%2, as flag will then only be values [0, 1]. If you replace flag with num, it should work as expected.

import requests
from bs4 import BeautifulSoup

num = int(input('''press 1 for tesco
press 2 for morrisions
press 3 for sainsbury's
'''))

print("please enter the food you want to search for: ")
flag = num                   # <--- notice this
txt = input("")

if flag == 1:
    markup = requests.get('https://www.tesco.com/groceries/en-GB/search?query=' + txt).text
elif flag == 2:
    markup = requests.get('https://groceries.morrisons.com/search?entry=' + txt).text
elif flag == 3:
    markup = requests.get('https://www.sainsburys.co.uk/webapp/wcs/stores/servlet/SearchDisplayView?catalogId=10123&langId=44&storeId=10151&krypto=OYaxfyCjgnRApUa%2FS%2BjRmgHslGfDEUtd3xECMndoz2f9gvq5KRuP8TuhW4m1jnUT%2FJU3fBivUiAIozuhmBLJJJQe6gcTedPJTASuwsZfLkt49e%2FYAPxDyWxCjeiyFxNN5WjSEdcW7LMdmfJbn3TmGVBZKVIxqu1zUw7IT8Qo2afgUyuCpJPcxPbmc2gWJMpi#langId=44&storeId=10151&catalogId=10123&categoryId=&parent_category_rn=&top_category=&pageSize=60&orderBy=RELEVANCE&searchTerm=' + txt).text

soup = BeautifulSoup(markup, 'lxml')
print(soup.prettify())


问:
Oracle users with role and previleges
I need a query which contains Oracle users with roles and  privileges  in one query

I Am using Oracle 11G

答: Of course roles can be granted to roles, granted to roles .... So if your intent is, as it seems, to see everything a given user has, regardless of directly granted or inherited through a role, through a role, through a role ...  Then the definitive script is found at Pete Finnigan's site.  See http://www.petefinnigan.com/find_all_privs.sql</p>

Title: Oracle users with role and previleges


问:
How do I merge rows dynamically in R?
I have the following data frame in R:

```<code>type,status,count
41,438421,512
41,438422,512
41,438429,269
74,440586,172
74,440590,217
</code>```

What I want to do is to merge the rows and rearrange data.  My desired output is shown below:

```<code>[41] = {["512"] = "438421, 438422", ["269"] = "438429",},
[74] = {["172"] = "440586", ["217"] = "440590",},
</code>```

The rows must be merged so that the type column is unique.  Then the status and counts should be added as shown above.

Note that the values of all these are not known so I can't reference anything by the value (such as 438421).  There are over 100,000 lines in the actual data frame and they all have different values for everything so the solution code needs to work regardless of what values are used above.

Many thanks.

答:
You can do it with dplyr...

```<code>library(dplyr)

df %>% group_by(type, count) %>%
  summarise(status = paste(status, collapse = ", ")) %>%
  mutate(count = paste0('["', count, '"] = "', status, '"')) %>%
  group_by(type) %>%
  summarise(count = paste(count, collapse = ", ")) %>%
  mutate(type = paste0('[', type, '] = {', count, ',},')) %>%
  select(type)

  type
  <chr>
1 "[41] = {[\"269\"] = \"438429\", [\"512\"] = \"438421, 438422\",},"
2 "[74] = {[\"172\"] = \"440586\", [\"217\"] = \"440590\",},"
</code>```

Don't worry about the backslashes in the above - they are just escaping the literal double quotes for the purposes of printing the output.

Title: How do I merge rows dynamically in R?

Body:
I have the following data frame in R:

type,status,count
41,438421,512
41,438422,512
41,438429,269
74,440586,172
74,440590,217

What I want to do is to merge the rows and rearrange data.  My desired output is shown below:

[41] = {["512"] = "438421, 438422", ["269"] = "438429",},
[74] = {["172"] = "440586", ["217"] = "440590",},

The rows must be merged so that the type column is unique.  Then the status and counts should be added as shown above.

Note that the values of all these are not known so I can't reference anything by the value (such as 438421).  There are over 100,000 lines in the actual data frame and they all have different values for everything so the solution code needs to work regardless of what values are used above.

Many thanks.

Body:
You can do it with dplyr...

library(dplyr)

df %>% group_by(type, count) %>%
  summarise(status = paste(status, collapse = ", ")) %>%
  mutate(count = paste0('["', count, '"] = "', status, '"')) %>%
  group_by(type) %>%
  summarise(count = paste(count, collapse = ", ")) %>%
  mutate(type = paste0('[', type, '] = {', count, ',},')) %>%
  select(type)

  type
  <chr>
1 "[41] = {[\"269\"] = \"438429\", [\"512\"] = \"438421, 438422\",},"
2 "[74] = {[\"172\"] = \"440586\", [\"217\"] = \"440590\",},"

Don't worry about the backslashes in the above - they are just escaping the literal double quotes for the purposes of printing the output.


问:
How to auto increment the primary key?
I have this sql query to create my Penguin table

```<code>CREATE TABLE Penguin (
PenguinID INTEGER PRIMARY KEY,
Name VARCHAR(10),
Height FLOAT,
Weight FLOAT)
</code>```

But then when I do INSERT INTO Penguin (Name, Height, Weight) VALUES (?,?,?) only the name, height and weight are added, and the PenguinID column is NULL

答:
just add AUTOINCREMENT besides the definition of the column within the CREATE TABLE statement as

PenguinID INTEGER PRIMARY KEY AUTOINCREMENT

Demo

Title: How to auto increment the primary key?

Body:
I have this sql query to create my Penguin table

CREATE TABLE Penguin (
PenguinID INTEGER PRIMARY KEY,
Name VARCHAR(10),
Height FLOAT,
Weight FLOAT)

But then when I do INSERT INTO Penguin (Name, Height, Weight) VALUES (?,?,?) only the name, height and weight are added, and the PenguinID column is NULL


问:
Blackout number in pdf using OCR
Have 3 pages PDF which has scanned Id card. Id card copy can be on any page I need to blackout Id card number (Format of Id card number - 12 Digits and two spaces i.e xxxx xxxx xxxx)

Please suggest how can i achieve this

I tried microsoft computer vision OCR services but unable to integrate the code

Need to automate this task

Find the Input and expected Output file
Input and Outputfile

答: I would locate qrcode (there are several packages of zbar for python) and clean area below it - dimension could be calculated by qr code size... </p>

Title: Blackout number in pdf using OCR


答:
Because of some strange defaults in SQLite, it does this automatically.  You can see here.

What is happening is that all tables have a rowid column that is auto-incremented.  An integer primary key is automatically a synonym for rowid, so it gets incremented.  This is explained in the documentation.

Don't get used to this behavior, because it is peculiar to SQLite.  You can define the column as autoincrement, although that adds a tad of overhead.

Title: How to auto increment the primary key?