MobX - Update multiple store array items at once? - mobx

I have 4 stores for a stack overflow example:
SearchQuestionsStore
RecentQuestionsStore
UserQuestionsStore
CurrentQuestionStore
Each of the first 3 stores have an #observable questionsList = [];
A question may be accessed from any of those 3 stores, when the questionsList is populated with questions. An #observable currentQuestion holds the current selected question in the CurrentQuestionStore
If a user upvotes the currentQuestion, we simply increment the current question's count using CurrentQuestionStore.currentQuestion.upvotes++, but this does not reflect the latest upvote count in the other 3 stores.
The issue is that the question may or may not exist in any of the other 3 stores questionlists, so I was wondering what would be the best way to approach this using MobX? So we can update the latest count for this questionId = 1 across all stores if they exist. The same situation occurs when changing the title, answers count, or any other attribute on the currentQuestion
What's the best way to reflect the changes of any attribute change across the stores at once?

With MobX, you should never have two copies of the same thing. The same question object should be referenced from all stores. To achieve this, it will depend on how your code is setup to load and store the questions.
One way I suggest doing this is to have an AllQuestionsStore that contains all questions in a map:
class AllQuestionsStore {
#observable questionsMap = asMap({});
#action addQuestion(question) {
const map = this.questionsMap;
if (map.has(question.id)) {
extendObservable(map.get(question.id), question);
} else {
map.set(question.id, question);
}
return map.get(question.id);
}
}
Then you whenever you create or load a question, you should add it to this store. For example, when you load user questions from the server:
function loadedUserQuestions(userQuestions) {
const questions = userQuestions.map(AllQuestionsStore.addQuestion, AllQuestionsStore);
UserQuestionsStore.questionsList = questions;
}
And if you want to set the current question:
CurrentQuestionStore.currentQuestion = AllQuestionsStore.addQuestion(question);
Now it's guaranteed that a question has only one instance, so if you update it, other stores will never be out of date.

Related

Magento 2 REST API understanding fields

Can someone explain the "status" and "visibility" fields on each product in the list obtained through Magento 2 REST API?
When calling the /products endpoint a list of products are returned but I'm having issues understanding the different fields. Sure, some fields are self explanatory like sku, name, etc. but others like status and visibility aren't.
Looking at the documentation, I can see both values are integers but no further explanation as to what values are allowed and what they actually mean? That makes the documentation kinda useless since I can probably just guess the type looking at the often related GET-request.
Documentation found here:
https://magento.redoc.ly/2.4.1-admin/tag/products#operation/catalogProductRepositoryV1GetListGet
I have no former experience with Magento :D
Maybe there is a reference list somewhere that explains each field?
Hope someone can help me!
If you have a look at four constants at the top of the class Visibility: https://github.com/magento/magento2/blob/2.4-develop/app/code/Magento/Catalog/Model/Product/Visibility.php
const VISIBILITY_NOT_VISIBLE = 1;
const VISIBILITY_IN_CATALOG = 2;
const VISIBILITY_IN_SEARCH = 3;
const VISIBILITY_BOTH = 4;
you will see what values are allowed and what they mean: IN_CATALOG means that the product will not be taken into account when user is using search, while IN_SEARCH means that the product will not show on product page and category page, but will be returned in search results, the other two (NOT_VISIBLE, BOTH) are a combination of these two both being false or both being true.
Now about status - have a look here: https://github.com/magento/magento2/blob/2.4-develop/app/code/Magento/Catalog/Model/Product/Attribute/Source/Status.php
Again, you have constants which are used to store the status:
/**
* Product Status values
*/
const STATUS_ENABLED = 1;
const STATUS_DISABLED = 2;
I hope this answers your question :)

How to create several new records in another SQL table from one button-click

I'm new here. Thanks in advance for your advice.
I’m working on an app which will ask the user how many items they made.
The user will enter a number. My app should then create that many new records in a table called 'Items_Made'.
E.g. The app asks “How many items did you make?”, the user enters “19”, the app then creates 19 new records in the 'Items_Made' table.
I've managed to pull together some code (shown below) that creates ONE new record, but I would like it to create several. I probably need some kind of loop or 'while' function but am unsure how to do so.
var ceateDatasource = app.datasources.Items_Made.modes.create;
var newItem = ceateDatasource.item;
ceateDatasource.createItem();
This code successfully creates 1 record. I would like it to be able to create several.
Creating a lot of records via client script is not recommended, especially if you loose connection or the app gets closed by mistake. In my opinion, the best way to handle this would be via server script for two things: First, It's more reliable and second, it's faster. As in the example from the official documentation, to create a record you need to do something like this:
// Assume a model called "Fruits" with a string field called "Name".
var newRecord = app.models.Fruits.newRecord();
newRecord.Name = "Kiwi"; // properties/fields can be read and written.
app.saveRecords([newRecord]); // save changes to database.
The example above is a clear example on how to create only one record. To create several records at once, you can use a for statement like this:
function createRecordsInBulk(){
var newRecords = [];
for(var i=0; i<19; i++){
var newRecord = app.models.Fruits.newRecord();
newRecord.Name = "Kiwi " + i;
newRecords.push(newRecord);
}
app.saveRecords(newRecords);
}
In the example above, you initiate newRecords, an empty array that will be responsible for holding all the new records to create at once. Then using a for statement, you generate 19 new records and push them into the newRecords. Finally, once the loop is finished, you save all the records at once by using app.saveRecords and passing the newRecords array as an argument.
Now, all this is happening on the server side. Obviously you need a way to call this from the client side. For that, you need to use the google.script.run method. So from the client side you need to do the following:
google.script.run.withSuccessHandler(function(result) {
app.datasources.Fruits.load();
}).createRecordsInBulk();
All this information is clearly documented on the app maker official documentation site. I strongly suggest you to always check there first as I believe you can get a faster resolution by reading the documentation.
I'd suggest making a dropdown or textbox where the user can select/enter the number of items they want to create and then attach the following code to your 'Create' button:
var createDatasource = app.datasources.Items_Made.modes.create;
var userinput = Number(widget.root.descendants.YourTextboxOrDropdown.value);
for (var i = 0; i <= userinput; i++) {
var newItem = createDatasource.item;
createDatasource.createItem();
}
Simple loop with your user input should get this accomplished.

In Parse Need to fetch nested relation data in one call

I am currently working with parse in react native.
I have a query that fetches data from a collection which has a property with relation to other collection.
Now i want to fetch all these relational data in a single call rather then calling each relation separately.
Currently i get one collection then get its relational data separately in a new call.
const data1 = await result
.get("data1")
.query()
.descending("createdAt")
.find();
const data2 = data1.relation("test");
const data3 = await data2.query().find();
Now i want to fetch the relational data along with the data1 in the very first call.
I would like to know is it even possible in parse.
If yes how?
I have been trying to fetch relational data all day but no success.
Any help would really be appreciated.
I hope you're fine :)
Using relations, you will need to fetch the data with more than a single call.
Why is it necessary?
It is required because the relation type creates a new collection on the database to store the relational data.
Please, take a look at the code below:
query.find().then(results => {
for (var i = results.length - 1; i >= 0; i--) {
let object = results[i];
object.relation("data1").query().each(function(relatedObject) {
console.log(relatedObject);
/* .... */
});
}
}).catch(console.error());
Is there another option to receive the data in a single call?
Yes, there is! To configure this option, you will need to use the pointer or array type, then you will be able to use include() method and get the column value, please read more about it below:
https://docs.parseplatform.org/js/guide/#one-to-many

firestore nested object field needs updating, not replacing

I am creating an app, where announcements are shown, stored in firestore and with that there is a hasRead object for each announcement.
It works, as in when a user is reading the announcement it is shown as read on the users app. But when another user is reading the same announcement, his/her usrid is being stored, overwriting the any other usrid stored.
Here his how I store it.
setAnnounceToRead(userId) {
firebase.firestore().collection('announcements').doc(this.state.id).set({
hasread: {
userId
}
},
{ merge: true });
}
I already found out that it is because of the merge, as it doesn't "adds" the usrid but overrides it instead.
How can I add every userid that reads the announcement, but keeping the already existing userids?
Cheers
Right now you're storing each user's UID as a field named userId. Since you're using the same field name for each user, you end up storing only the last user's UID.
To store the UID for all users, you'd usually have a structure like this:
hasread: {
udartsUid: true,
pufsUid: true
}
In your code that would translate to something like:
let update = {};
update[userId] = true;
firebase.firestore().collection('announcements').doc(this.state.id).set({
hasread: update
},
{ merge: true });
But this type of operation got a lot easier recently, since Firestore now has operations that allow you to use an array for this type of information.
let doc = firebase.firestore().collection('announcements').doc(this.state.id);
doc.update({ "hasRead": FieldValue.arrayUnion(userId) });
This snippets will add the userId value to the array if it isn't already in there. If the value is already in the array, it does nothing.
For more on the latter, see the blog post Better arrays in Cloud Firestore.

Data structure to use in Sencha Touch similar to Vector in Blackberry

I am a beginner to sencha Touch, basically i am a blackberry developer. Currently we are migrating our application to support Sencha Touch 1.1. Now i have some business solutions like i want to store the selected values in the local database. I mean i have multiple screens where, Once the user selects a value in each of the screen the data should save in the below following format.
[{'key1': "value1", 'key2': "value2", 'key3': "value3" ,'key4': "value4", 'key5': "value5"}]
1. First, the values need to be saved in key value pairs
2. The keys should play the role of primary key, key shouldn't be duplicated.
3. Should be available till the application life cycle or application session, don't need to save the data permanently.
I have come across the concepts like LocalStorageProxy, JsonStore and some others. I don't understand which one i can use for my specific requirements.
May be my question is bit more confusing. I have achieved the same using vector, in Blackberry Java so any data structure similar to this could help me. Need the basic operations like
Create
Add
Remove
Remove all
Fetch elements based on key
Please suggest me some samples or some code snapshots, which may help me to achieve this.
Edit: 1
I have done the changes as per #Ilya139 's answer. Now I am able to add the data with key,
// this is my Object declared in App.js
NSDictionary: {},
// adding the data to object with key
MyApp.NSDictionary['PROD'] = 'SONY JUKE BOX';
//trying to retrieve the elements from vector
var prod = MyApp.NSDictionary['PROD'];
Nut not able to retrieve the elements using the above syntax.
If you don't need to save the data permanently then you can just have a global object with the properties you need. First define the object like this:
new Ext.Application({
name: 'MyApp',
vectorYouNeed: {},
launch: function () { ...
Then add the key-value pairs to the object like this
MyApp.vectorYouNeed[key] = value;
And fetch them like this
value = MyApp.vectorYouNeed[key];
Note that key is a string object i.e. var key='key1'; and value can be any type of object.
To remove one value MyApp.vectorYouNeed[key] = null; And to remove all of them MyApp.vectorYouNeed = {};