Im using an observable to set a value in a different component. So in my NavigationComponent I have:
import toggleAside$ = SomeService.toggleAside$;
public toggleAdditionalInformation() {
toggleAside$.onNext(false);
}
And in the other component I have:
export const toggleAside$ = new Rx.Subject();
public showAside: boolean;
private toggleAsideView(): void {
toggleAside$.subscribe(() => {
this.showAside = !this.showAside;
});
}
I have a button the calls the toggleAdditionalinformation() function. This will create a stream with a false boolean value. In my other component I subscribe to the toggleAside$ stream. When something happens it will change the class propperty showAside. My code works as I want. But the value in the onNext() is not being used for anything. But it requires 1 parameter.
So am I abusing the onNext() function for this or is there a different solution with the parameters? An empy null object or something?
I'm using rx-lite Release 4.0.8
Related
In the calculator example, I have added a new interface in the capnp file like below:
interface Main {
getCalculator #0 () -> (calculator :Calculator);
}
My objective is to make use of multiple interfaces through one implementation Main. How can I achieve this? The extra client code is below (when I try to use calculator it throws a null capability exception):
capnp::EzRpcClient client1(argv[1]);
Main::Client main = client1.getMain<Main>();
auto& waitScope1 = client1.getWaitScope();
auto request1 = main.getCalculatorRequest();
auto evalPromise1 = request1.send();
auto response1 = evalPromise1.wait(waitScope1);
auto calculator = response1.getCalculator();
auto request = calculator.evaluateRequest();
request.getExpression().setLiteral(123);
// Send it, which returns a promise for the result (without blocking).
auto evalPromise = request.send();
// Using the promise, create a pipelined request to call read() on the
// returned object, and then send that.
auto readPromise = evalPromise.getValue().readRequest().send();
// Now that we've sent all the requests, wait for the response. Until this
// point, we haven't waited at all!
auto response = readPromise.wait(waitScope1);
KJ_ASSERT(response.getValue() == 123);
Changes to the server's main implementation file are given below:
class MainImpl : public Main::Server {
public:
kj::Promise<void> getCalculator(GetCalculatorContext context) override {
context.getResults();
return kj::READY_NOW;
}
};
The main function in server serves MainImpl. I do get the calculator object but how can I further invoke methods on that object?
Your getCalculator() function on the server side does not do anything right now. You need to actually set the result if you want the Calculator to get back to the client. That's why you get your "null capability exception".
Something like this:
class MainImpl : public Main::Server {
public:
kj::Promise<void> getCalculator(GetCalculatorContext context) override {
context.getResults().setCalculator(<the calculator capability>);
return kj::READY_NOW;
}
};
That will require you to create the Calculator client on the server side (i.e. you won't do Calculator::Client calculator = client.getMain<Calculator>(); on the client side anymore, since calculator will come from getCalculator()).
I have this link that changes the final of the url with a time stamp:
getAvatar(channelId): BehaviorSubject<string> {
return new BehaviorSubject(`${link}?${new Date().getTime()}`);
}
And in the Avatar Component, that is a child of at least 10 other components i call this subscribe:
getAvatar() {
this.userService.getAvatar(this.channelId)
.subscribe(res => {
this.avatar = res;
this.cdr.detectChanges();
this.cdr.markForCheck();
});
}
OBS: Im using the OnPush changeDetection strategy
And in another component i have a function that changes this profile picture inside the link:
this.userService.changeProfilePicture(picture, this.myChannelId)
.subscribe(
() => {
this.loading.hide();
this.userService.getAvatar(this.id);
this.screenService.showToastMessage('Foto de perfil alterada.', true);
}
As you can see, im recalling the getAvatar() function that returns a BehaviorSubject to generate another link and the AvatarComponent doenst detect the change of the behaviorSubject, what im doing wrong ?
And theres another way to recall the getAvatar() function of all the AvatarComponent instances to reload each avatar instance ?
OBS2: I tried to use of rxjs operator, creating a new Observable(), tried the Subject class, all of those seems to not get detected by the subscribe inside the AvatarComponent
OBS3: I tried to get the AvatarComponent with #ViewChild() and call this this.avatarCmp.getAvatar(); to reload the avatar, but reloads just one instance of the Avatar Component
your service needs to be more like this:
private avatarSource = new BehaviorSubject(`${link}?${new Date().getTime()}`);
avatar$ = this.avatarSource.asObservable();
setAvatar(channelId): BehaviorSubject<string> {
this.avatarSource.next(`${link}?${new Date().getTime()}`);
}
then you need to subscribe to avatar$ and update with setAvatar
I think I understand the concept of Observables in Rxjs but I am struggling to convert the theory into code.
I have an Angular component, say C. I want that it should show certain HTML components depending on whether the user is logged in or not. For this I am using the code similar to
<ng-container *ngIf = "userNotloggedIn">
...
I have an Angular Service which authenticates the user. I want that once the user is authenticated, the service should emit a value (say boolean true or false corresponding to signin and sign out). I will like to use an Observable for this and my component should subscribe to this Observable.
I am struggling to convert this into code. I my service, I have created an Observable as follows and then I emit the values (true or false) when the user signs in or signs out:
export class UserManagementService {
userSignedIn$: Observable<boolean>;
constructor(private http: HttpClient, private bs:WebToBackendInterfaceService) {
this.userSignedIn$ = Rx.Observable.of(false)
}
onUserSignout(){
console.log("In UserManagementService: onUserSignout")
return this.bs.onUserSignout().subscribe((res/*:ServerResponse*/)=>{
console.log("response fromm server",res)
this.userSignedIn$ = Rx.Observable.of(false)
}); //res is of type HttpResponse
}
signinUser(user:UserSigninInfo){
return this.bs.signinUser(user).subscribe((res:HttpResponse<any>)=>{console.log('response from server:',res);
console.log('response headers',res.headers.keys())
this.userSignedIn$ = Rx.Observable.of(true)
} )
}
Then in the component, I subscribe to the observable as follows:
ngOnInit(){
this.userloggedIn = false;
this.userManagementService.userSignedIn$.subscribe(x=>{console.log("got stream value ",x);
this.userloggedIn = x})
...
}
The above code doesn't work though. I get the very first value emitted by the Observable (corresponding to this.userManagementService.userSignedIn$.subscribe(x=>{console.log("got stream value ",x);) but nothing after that.
I suspect that it could be because I subscribe to the initial Observable but not to the new ones created in the signin and signout functions. How can I solve my problem?
Observable.of(true) returns a cold observable which cannot emit new values over time.
use Behavior Subject for userSignedIn$ instead
userSignedIn$=new BehabviorSubject();
and when you want to update the signin status use
userSignedIn$.next(true)
I'm trying to use callMethod() from a method executed on the server.
In this case, I should be able to call it in synchronous mode. However, through trial and error I have found that in this context (i.e. on the server), the method requires three parameters rather than the two mentioned in the docs.
It requires
the first parameter to be a string
the second parameter to be an array
the third parameter to be an object
I've tried quite a few combinations with these parameters but nothing seems to work. At the same time, Wakanda doesn't throw an error as long as the parameters are in the correct form.
Any ideas would be more than welcome.
TIA
Let's suppose we have two variable, one containing the name of the dataClass and the second the name of the dataClass's method :
var myDataClass = "User";
var myMethod = "addUser";
To use the dataClass 'User' and call the method 'addUser' you can do it this way :
var currentClass = ds.dataClasses[myDataClass];
currentClass[myMethod]()
The method callMethod() is a clientSide method, it should be used on prototyper Js files.
try to use it on a button.click event :
button1.click = function button1_click (event)
{
ds.User.callMethod({method:"method1", onSuccess:myFunction, onError:failure});
function myFunction(){
return true;
}
function failure(){
return false;
}
};
To call method in a serverSide js File in a synchronous mode, you can just make the call in this manner :
var test = ds.User.method1();
Is it possible to set a fallback callback which is called when the user wants to call a function which does not exists? E.g.
my_object.ThisFunctionDoesNotExists(2, 4);
Now I want that a function is getting called where the first parameter is the name and a stack (or something like that) with the arguments passed. To clarify, the fallback callback should be a C++ function.
Assuming your question is about embedded V8 engine which is inferred from tags, you can use harmony Proxies feature:
var A = Proxy.create({
get: function (proxy, name) {
return function (param) {
console.log(name, param);
}
}
});
A.hello('world'); // hello world
Use --harmony_proxies param to enable this feature. From C++ code:
static const char v8_flags[] = "--harmony_proxies";
v8::V8::SetFlagsFromString(v8_flags, sizeof(v8_flags) - 1);
Other way:
There is a method on v8::ObjectTemplate called SetNamedPropertyHandler so you can intercept property access. For example:
void GetterCallback(v8::Local<v8::String> property,
const v8::PropertyCallbackInfo<v8::Value>& info)
{
// This will be called on property read
// You can return function here to call it
}
...
object_template->SetNamedPropertyHandler(GetterCallback);