Detect DOM changes with Mutation Observers

            let target = document.getElementById(Post.ViewModel.postURLId);
            let observer = new MutationObserver(function (mutations) {
                mutations.forEach(function (mutation) {
                    console.log(mutation);
                });
            });
            let config = {
                attributes: true, childList: true, characterData: true, subtree: true,
                attributeOldValue: true, characterDataOldValue: true
            };
            observer.observe(target, config);
            // later, you can stop observing
            observer.disconnect();
if (target.addEventListener) {
                target.addEventListener('input', function(e) {
                    console.log(e);
                }, false);
            }

So with the help of above two tricks and browser breakpoints and stacktrace we can detect exact source of error.

References
https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

Configure MongoDB in Spring Data

build.gradle

compile("org.springframework.boot:spring-boot-starter-data-mongodb")
compile group: 'org.mongodb', name: 'mongo-java-driver', version: '3.4.2'

application.properties

spring.data.mongodb.uri=mongodb://localhost/pupli

User

import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.Document

@Document(collection = "users")
public class User implements Serializable {

    @Id
    public String id;

    public String userName;

    public String password;

    public String firstName;

    public String lastName;

    public static String COL1_id(){
      return "id"
    }

    public static String COL2_userName()
    {
        return "userName"
    }

    public static String COL3_password()
    {
        return "password"
    }

    public static String COL4_firstName()
    {
        return "firstName"
    }

    public static String COL5_lastName()
    {
        return "lastName"
    }
}

References
https://spring.io/guides/gs/accessing-data-mongodb/
http://www.baeldung.com/spring-data-mongodb-tutorial
https://www.mkyong.com/mongodb/spring-data-mongodb-hello-world-example/
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-nosql.html

Configure Spring Session with Redis

build.gradle

compile('org.springframework.session:spring-session')
compile('org.springframework.boot:spring-boot-starter-data-redis')

application.properties

spring.session.store-type=redis

spring.redis.host=localhost
#spring.redis.password=secret
spring.redis.port=6379

Working with SharedPreferences

    public void calculateAndShow(boolean swapRanges) {
        float value = 24;
        UserBL userBL = new UserBL(getContext());
        User user = userBL.getActiveUser();

        BMI bmi = new BMI(user.getLatestHeight(), user.getLatestWeight());
        value = Float.parseFloat(String.format(Locale.US, "%.2f", bmi.calculate()));

        String name = user.getName();
        String age = String.valueOf(calculateAge(user.getBirthdate()));
        String height = String.valueOf(user.getLatestHeight());

        textViewProfileInfoAge.setText(String.format(Locale.US, "%s سال", age));
        textViewProfileInfoName.setText(String.format(Locale.US, "%s", name));
        textViewProfileInfoHeight.setText(String.format(Locale.US, "%s سانتی متر", height));

        gauge.setHighValue(value, 12, 44);

        textViewBMI.setText(String.valueOf(value));

        textViewCurrentWeight.setText(String.format(Locale.US, "%s کیلوگرم", user.getLatestWeight()));

        FragmentManager fragmentManager = getFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        SharedPreferences sharedPreferences = getContext().getSharedPreferences("bmi", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();

        if (!swapRanges) {

            if (sharedPreferences.getInt("bmi_range", -1) == -1) {

                BmiRangeFragment bmiRangeFragment = new BmiRangeFragment();
                fragmentTransaction.replace(R.id.linearLayoutRangeContainer, bmiRangeFragment);

            } else if (sharedPreferences.getInt("bmi_range", -1) == 1) {

                BmiRangeFragment bmiRangeFragment = new BmiRangeFragment();
                fragmentTransaction.replace(R.id.linearLayoutRangeContainer, bmiRangeFragment);

            } else if (sharedPreferences.getInt("bmi_range", -1) == 2) {
                WeightRangeFragment weightRangeFragment = new WeightRangeFragment();

                Bundle bundle = new Bundle();
                bundle.putSerializable("bmi", bmi);
                weightRangeFragment.setArguments(bundle);

                fragmentTransaction.replace(R.id.linearLayoutRangeContainer, weightRangeFragment);

            }

            fragmentTransaction.commit();

        } else {

            Fragment previousFragment = fragmentManager.findFragmentById(R.id.linearLayoutRangeContainer);

            if (previousFragment instanceof WeightRangeFragment) {

                BmiRangeFragment bmiRangeFragment = new BmiRangeFragment();

                fragmentTransaction.setCustomAnimations(R.anim.scale_up, R.anim.scale_down)
                        .replace(R.id.linearLayoutRangeContainer, bmiRangeFragment);

                editor.putInt("bmi_range", 1);

            } else if (previousFragment instanceof BmiRangeFragment) {
                WeightRangeFragment weightRangeFragment = new WeightRangeFragment();

                Bundle bundle = new Bundle();
                bundle.putSerializable("bmi", bmi);
                weightRangeFragment.setArguments(bundle);


                fragmentTransaction.setCustomAnimations(R.anim.scale_up, R.anim.scale_down)
                        .replace(R.id.linearLayoutRangeContainer, weightRangeFragment);

                editor.putInt("bmi_range", 2);
            }

            fragmentTransaction.commit();
            editor.apply();
        }
    }

References
https://www.tutorialspoint.com/android/android_shared_preferences.htm

Pass custom object in Bundle

package com.sam.bundleobjectpass;

import java.io.Serializable;

/**
 * Created by Samir on 31.8.2016.
 */
public class Model implements Serializable {
    private String name;
    private String surName;
    private int age;

    public Model(String name, String surName, int age) {
        this.name = name;
        this.surName = surName;
        this.age = age;
    }

    public String getName() {
        return name;
    }


    public String getSurName() {
        return surName;
    }


    public int getAge() {
        return age;
    }


}

MainActivity.java

public class MainActivity extends AppCompatActivity {

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


        Model model = new Model("Sam", "Sami",32);

        Intent i = new Intent(MainActivity.this, ReceiverActivity.class);
        i.putExtra("Editing", model); // sending our object
        startActivity(i);

    }
}

ReceiverActivity.java

public class ReceiverActivity extends Activity {

    TextView txt_name;
    TextView txt_surname;
    TextView txt_age;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second);

        txt_name = (TextView)findViewById(R.id.txt_name);
        txt_surname = (TextView)findViewById(R.id.txt_surname);
        txt_age = (TextView)findViewById(R.id.txt_age);
        // receiving our object
        Model model = (Model) getIntent().getSerializableExtra("Editing");

        txt_name.setText(model.getName());
        txt_surname.setText(model.getSurName());
        txt_age.setText(""+model.getAge());


    }
}

References
https://stackoverflow.com/questions/5784231/how-to-pass-custom-object-in-bundle

Receive JSON data in Spring Boot MVC Controller

FormsApiController.java

@RequestMapping(value = "/api/form/saveForm", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public Map saveForm(HttpServletRequest request, HttpServletResponse response, @RequestBody String payload) {
        SessionManager sessionManager = new SessionManager(request, response);

        Map result = null;

        FormBL formBL = new FormBL(request, response);
        result = formBL.saveForm(payload);

        return result;
    }

FormBL.java

    public Map<String, Object> saveForm(String payload) {
        Map<String, Object> result = new HashMap<>();

        try {

            Gson gson = new Gson();
            PojoForm pojoForm = gson.fromJson(payload, PojoForm.class);

            Form form = new Form();
            if (pojoForm.formId > 0) {
                form.id = pojoForm.formId;
            }


            Machinery machinery = null;

            if (pojoForm.machineryId > 0) {
                machinery = Statics.machineryRepository.findById(pojoForm.machineryId);
            }

            form.name = pojoForm.formName;
            form.machinery = machinery;

            Form dbForm = Statics.formRepository.save(form);
            pojoForm.formId = dbForm.id;

            if (pojoForm.formRows.size() > 0) {
                for (PojoFormRow row : pojoForm.formRows) {
                    FormRow formRow = new FormRow();

                    if (row.getId() > 0) {
                        formRow.id = row.getId();
                    }

                    formRow.rowOrder = row.row_order;
                    formRow.rowType = row.getRowType();
                    formRow.title = row.getTitle();
                    formRow.form = dbForm;

                    FormRow dbFormRow = Statics.formRowRepository.save(formRow);
                    row.id = dbFormRow.id;

                    if (row.getRow_values().size() > 0) {
                        for (PojoRowValue rowValue : row.getRow_values()) {
                            RowSelectValue rowSelectValue = new RowSelectValue();

                            if (rowValue.getId() > 0) {
                                rowSelectValue.id = rowValue.getId();
                            }

                            rowSelectValue.title = rowValue.title;
                            rowSelectValue.titleOrder = rowValue.title_order;
                            rowSelectValue.formRow = dbFormRow;

                            RowSelectValue dbRowSelectValue = Statics.rowSelectValueRepository.save(rowSelectValue);
                            rowValue.id = dbRowSelectValue.id;
                        }
                    }
                }
            }

            result.put("form", "");
            result.put("error", 0);
        } catch (Exception ex) {
            // exception
            result.put("error", 1);
            ex.printStackTrace();
        }

        return result;
    }

Android show DialogFragment title on API level older than 23

In your styles:

    <style name="CustomDialog" parent="@style/Theme.AppCompat.Light.Dialog">
        <item name="android:windowNoTitle">false</item>'
        <item name="android:layoutDirection">rtl</item>
        <item name="android:textDirection">rtl</item>
    </style>

If your dialog is a fragment:

MyFragment myFragment = new MyFragment();
myFragment.setStyle(DialogFragment.STYLE_NORMAL, R.style.CustomDialog);

References
https://stackoverflow.com/questions/32405042/android-dialogfragment-title-not-showing