Yii2 - how to pass parameters in event - yii

I need to pass additional parameters when the event is fired. How can I do this.
const EVENT_NEW_PORTAL = 'new-portal';
public function init(){
$this->on(self::EVENT_NEW_PORTAL, [$this, $userID, 'defaultJournal']);
$this->on(self::EVENT_NEW_PORTAL, [$this->idportal, $userID, 'defaultCategory']);
}
public function defaultJournal($portal, $userID)
{
CsJournal::insertDefaultJournal($portal, $userID);
}
public function defaultBoardCagetory($portalID, $userID)
{
BoardCategories::createDefaultCategory($portal, $userID);
}

You should read this : Attaching Event Handlers.
When attaching an event handler, you may provide additional data as the third parameter to yii\base\Component::on(). The data will be made available to the handler when the event is triggered and the handler is called.
e.g. :
public function defaultJournal($event)
{
CsJournal::insertDefaultJournal($this, $event->data);
}
And then :
$this->on(self::EVENT_NEW_PORTAL, [$this, 'defaultJournal'], $userID);

Related

how i know blazor OnInitializedAsync exec in once or twice

I want get data from db once on OnInitializedAsync. I try to use tableLoading to judue,but it's not work.
protected override async Task OnInitializedAsync()
{
if (tableLoading)
{
return;
}
tableLoading = true;
users = await userService.GetSome(1, userType);
_total = await userService.GetCount(userType);
tableLoading = false;
Console.WriteLine("OnInitializedAsync");
}
This is the official way to solve your problem. You have to persist component state during first load so that your services won't be called second time during second load.
First add <persist-component-state /> tag helper inside your apps body:
<body>
...
<persist-component-state />
</body>
Then inject PersistentComponentState in your component and use like this:
#implements IDisposable
#inject PersistentComponentState ApplicationState
#code {
private IEnumerable<User> _users;
private int _total;
private PersistingComponentStateSubscription _persistingSubscription;
protected override async Task OnInitializedAsync()
{
_persistingSubscription =
ApplicationState.RegisterOnPersisting(PersistState);
if (!ApplicationState.TryTakeFromJson<IEnumerable<User>>("users", out var restoredUsers))
{
_users = await userService.GetSome(1, userType);
}
else
{
_users = restoredUsers;
}
if (!ApplicationState.TryTakeFromJson<int>("total", out var restoredTotal))
{
_total = await userService.GetCount(userType);
}
else
{
_total = restoredTotal;
}
}
private Task PersistState()
{
ApplicationState.PersistAsJson("users", _users);
ApplicationState.PersistAsJson("total", _total);
return Task.CompletedTask;
}
void IDisposable.Dispose()
{
_persistingSubscription.Dispose();
}
}
How i know blazor OnInitializedAsync exec in once or twice?
It usually loads twice.
Once when the component is initially rendered statically as part of the page.
A second time when the browser renders the component.
However, If you want to load it once, in that case, you could go to _Host.cshtml and change render-mode="ServerPrerendered" to render-mode="Server", and it would be called only once as a result it would then load your data from the database once only.
Note: For more information you could refer to the official documents here.
I know it's usually loads twice, i want to know when the function is run, how to konw it's run on once or twice. This is my solution.
static bool first = true;
protected override async Task OnInitializedAsync()
{
if (first)
{
first = false;
Console.WriteLine("first time");
return;
}
Console.WriteLine("second time");
}

Why documentt.data.getValue() gives empty string? [duplicate]

A custom object that takes a parameter of (DocumentSnapShot documentsnapShot). also is an inner object from Firebase that retrieves a snapshot and set the values to my custom model also have its argument (DocumentSnapShot documentsnapShot). However, I wish to get the data from Firebase and pass it to my custom argument because mine takes multiple data not only Firebase. And it's not possible to iterate Firestore without an override.
Here's the code:
public UserSettings getUserSettings(DocumentSnapshot documentSnapshot){
Log.d(TAG, "getUserSettings: retrieving user account settings from firestore");
DocumentReference mSettings = mFirebaseFirestore.collection("user_account_settings").document(userID);
mSettings.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
UserAccountSettings settings = documentSnapshot.toObject(UserAccountSettings.class);
settings.setDisplay_name(documentSnapshot.getString("display_name"));
settings.setUsername(documentSnapshot.getString("username"));
settings.setWebsite(documentSnapshot.getString("website"));
settings.setProfile_photo(documentSnapshot.getString("profile_photo"));
settings.setPosts(documentSnapshot.getLong("posts"));
settings.setFollowers(documentSnapshot.getLong("followers"));
settings.setFollowing(documentSnapshot.getLong("following"));
}
});
}
You cannot return something now that hasn't been loaded yet. Firestore loads data asynchronously, since it may take some time for this. Depending on your connection speed and the state, it may take from a few hundred milliseconds to a few seconds before that data is available. If you want to pass settings object to another method, just call that method inside onSuccess() method and pass that object as an argument. So a quick fix would be this:
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
UserAccountSettings settings = documentSnapshot.toObject(UserAccountSettings.class);
yourMethod(settings);
}
One more thing to mention is that you don't need to set the those values to object that already have them. You are already getting the data from the database as an object.
So remember, onSuccess() method has an asynchronous behaviour, which means that is called even before you are getting the data from your database. If you want to use the settings object outside that method, you need to create your own callback. To achieve this, first you need to create an interface like this:
public interface MyCallback {
void onCallback(UserAccountSettings settings);
}
Then you need to create a method that is actually getting the data from the database. This method should look like this:
public void readData(MyCallback myCallback) {
DocumentReference mSettings = mFirebaseFirestore.collection("user_account_settings").document(userID);
mSettings.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
UserAccountSettings settings = documentSnapshot.toObject(UserAccountSettings.class);
myCallback.onCallback(settings);
}
});
}
In the end just simply call readData() method and pass an instance of the MyCallback interface as an argument wherever you need it like this:
readData(new MyCallback() {
#Override
public void onCallback(UserAccountSettings settings) {
Log.d("TAG", settings.getDisplay_name());
}
});
This is the only way in which you can use that object of UserAccountSettings class outside onSuccess() method. For more informations, you can take also a look at this video.
Use LiveData as return type and observe the changes of it's value to execute desired operation.
private MutableLiveData<UserAccountSettings> userSettingsMutableLiveData = new MutableLiveData<>();
public MutableLiveData<UserAccountSettings> getUserSettings(DocumentSnapshot documentSnapshot){
DocumentReference mSettings = mFirebaseFirestore.collection("user_account_settings").document(userID);
mSettings.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
#Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
UserAccountSettings settings = documentSnapshot.toObject(UserAccountSettings.class);
settings.setDisplay_name(documentSnapshot.getString("display_name"));
settings.setUsername(documentSnapshot.getString("username"));
settings.setWebsite(documentSnapshot.getString("website"));
settings.setProfile_photo(documentSnapshot.getString("profile_photo"));
settings.setPosts(documentSnapshot.getLong("posts"));
settings.setFollowers(documentSnapshot.getLong("followers"));
settings.setFollowing(documentSnapshot.getLong("following"));
userSettingsMutableLiveData.setValue(settings);
}
});
return userSettingsMutableLiveData;
}
Then from your Activity/Fragment observe the LiveData and inside onChanged do your desired operation.
getUserSettings().observe(this, new Observer<UserAccountSettings>() {
#Override
public void onChanged(UserAccountSettings userAccountSettings) {
//here, do whatever you want on `userAccountSettings`
}
});

Flutter Mockito verify that callback passed to widget is called

I have a widget that takes a callback which is called when a button is pressed. I am trying to test that the callback is correctly invoked by the button.
I've tried mocking a Function class:
class MockCallback extends Mock implements Function {
call() {}
}
Then passing an instance of the mock class to my widget and simulating a tap:
final mocked = MockCallback();
await tester.pumpWidget(
MyWidget(myCallback: mocked),
);
final clearButtonFinder = find.byType(IconButton);
await tester.tap(clearButtonFinder);
verify(mocked()).called(1);
This results in an error on the verify call saying Used on a non-mockito object. If I put a print statement inside the mocked call, I can see that the tap is indeed calling it.
How can I verify that the callback passed to my widget is getting called once when the button is tapped?
This is how I solved this problem.
class MockCallback {
int _callCounter = 0;
void call() {
_callCounter += 1;
}
bool called(int expected) => _callCounter == expected;
void reset() {
_callCounter = 0;
}
}
No mockito needed.
Probably it is not the best solution - use a stream:
final callbackCalled = BehaviorSubject<void>.seeded(null);
await tester.pumpWidget(
MyWidget(myCallback: () { callbackCalled.add(null); }),
);
//... actions to trigger the callback
await expectLater(callbackCalled, emitsInOrder(<void>[null, null]));
You can use something meaningful instead of 'void' and 'null'.

Get All Property's From A User in Flash CS2

I have this:
public function saveProfile() {
this.setProperty("picture",factory.getClass("userProfile").getProperty("picture"),"no");
this.setProperty("gender",factory.getClass("userProfile").getProperty("gender"),"no");
this.setProperty("state",factory.getClass("userProfile").getProperty("state"),"no");
this.setProperty("city",factory.getClass("userProfile").getProperty("city"),"no");
this.setProperty("marital",factory.getClass("userProfile").getProperty("marital"),"no");
this.setProperty("about",factory.getClass("userProfile").getProperty("about"),"no");
}
factory.getClass("userProfile") functions:
public function setProperty(property:String, value:String) {
_profile[property] = value;
}
public function getProperty(property:String) {
if (_profile[property] == undefined) {
return "";
}
return _profile[property];
}
what i wanna do is:
this getProperty - setProperty returns the values from a specific user.
I want to get the properties from another user ex:
public function saveProfile(username:String) {
this.setProperty("picture",factory.getClass("userProfile").getProperty("picture"),"no"); ->
from the user username:String i ask to
etc...
}
If anyone can help me to change the getProperty, setProperty functions in the userprofile class to give me the property's from the username i ask.
Thanks a lot!
Regards

Is there a way to manually raise the PropertyChanged event of an EntityObject?

Hi I am trying to raise the PropertyChanged event of an EntityObject, I don't find a way to do it, is this possible?
OnPropertyChanged("PropertyName")
You should be able to decorate the property with an attribute and then call the ReportPropertyChanging and ReportPropertyChanged method like so:
[EdmScalarPropertyAttribute(IsNullable = false)]
public byte Status
{
get
{
return _status;
}
set
{
if (_status != value)
{
ReportPropertyChanging("Status");
_status = value;
ReportPropertyChanged("Status");
}
}
}