I'm trying to display the username in the navbar. I managed to do it using my profile service like this:
let user of profileService.getProfile(), which uses the subscribe in order to retrieve the data.
However, the first time that I log in the name won't pop out. If I refresh the browser, the name will be displayed. I guess that it has something to do with the subscribe and its asynchronous nature, but if that's the case, what would be the best solution to the problem?
As you mentioned in the comment your getProfile() returns an observable.
You can subscribe to it in your component and then display the user name in your HTML component:
userName: string;
constructor(private profileService: ProfileService){}
ngOnInit(): void {
this.profileService.getProfile().subscribe((resp)=>{
//Assuming response only returns username
this.userName = resp;
});
}
and then in your HTML you can just bind to userName.
<div>
Logged in user name is: {{userName}}
</div>
I think that you can create a BehaviorSubject in service, it has a method getValue() that give a current value :
user$ : BehaviorSubject<String> = new BehaviorSubject("");
setProfile() {
this.user$.next("newName");
}
getProfile(): string {
return this.user$.getValue();
}
In View, you can use a pipe (AsyncPipe) to subscribe observable like :
{{ userOfProfileService$ | async }}
However, you can also use Subject observable without getProfile() but just with AsyncPipe in view.
user$ : Subject<String> = new Subject();
Related
community
I implemented stream-chat & stream-chat-react getStream
Hi, I want to show the system message on some events
For Ex: User A added User B to the chat (Here user A and User B is the name of both user but I don't want to send those message as it is because I want if user A changes their name to USER X then those previous messages also updated.) I want guidance on how I can achieve this.
Stream is allowing me to send system messages with the addMemberToChannel event but I am not able to find how I can use it for my specific case.
Expected Output:
For your case, you will avoid saving hardcoded data in the message's text property.
First, you create a system message on adding a user to a channel like this:
channel.addMembers([userId], {
text: 'added_users',
mentioned_users: [userId],
});
With the addMembers method on a channel object, you can add members to a channel and also pass a message object.
The message object accepts the message text and the mentioned_users properties.
You can use added_users or any text that you want to keep as a standard message for adding-members-system-message. You'll see why I use "added_users" in a second.
The Channel component renders system messages using the EventComponent. This component displays the text of the system message, with the date and some added styles.
You can create a custom event message component for your added_users message. This component can look like this:
import { EventComponent } from 'stream-chat-react';
function CustomEventMessage(props) {
const { message } = props;
const { text, mentioned_users, user } = message;
if (text === 'added_users') {
const message = user?.name + ' added ' + mentioned_users[0].name;
return (
<div className="str-chat__message--system">
<div className="str-chat__message--system__text">
<div className="str-chat__message--system__line"></div>
<p>{message}</p>
<div className="str-chat__message--system__line"></div>
</div>
</div>
);
}
// use the default event component
return <EventComponent {...props} />;
}
The CustomEventMessage component above accepts a message object prop which has the:
text: system message text
mentioned_users: mentioned users in the message
user: user who triggered the message
Next, you check if the text is added_users. If it is, then you provide a custom UI and message, which consists of the name of the user who triggered the message and the mentioned user (who was added to the channel)
I also used classnames from Stream's stylesheets so that I don't have to build mine.
Next, you add this component to the Channel component:
<Channel MessageSystem={CustomEventMessage}>
// ...
</Channel>
The message will now read as "Person X added Person Y" as seen in the image below:
If the text is not added_users, you pass the props to the default EventComponent.
Since you're saving the id of the mentioned user and not hardcoding the text ("Person A added Person B"), you will also get updated details about the users, even when they update their information.
I have developed a lightning component modal popup to show on the opportunity page. There are two options Yes and No. On condition this lightning component is transferring the flow to one visualforce page or the other with the account id. How I can get the account id in the lightning component.
<aura:component implements="force:lightningQuickActionWithoutHeader">
Are you sure you want to proceed?
<div class="slds-align_absolute-center">
<lightning:button
label="No"
variant="destructive"
onclick="{!handleNo}"
></lightning:button>
<lightning:button label="Yes" onclick="{!c.handleYes}"></lightning:button>
</div>
</aura:component>
and the controller is
({
handleNo: function (component, event, helper) {
var urlEvent = $A.get("e.force:navigateToURL");
urlEvent.setParams({
url: "/apex/MyOtherVisualforce",
isredirect: "true"
});
urlEvent.fire();
},
handleYes: function (component, event, helper) {
var urlEvent = $A.get("e.force:navigateToURL");
urlEvent.setParams({
url: "/apex/MyVisualforce",
isredirect: "true"
});
urlEvent.fire();
}
});
In order to obtain the Account Id from the Opportunity, first you need to get the Opportunity Id where the Quick Action is being executed. That can be easily achieved by implementing the force:hasRecordId interface (in addition to the lightningQuickActionWithoutHeader one that you are already implementing). By doing this, you get access to recordId attribute which already contains the record id of the Opportunity in this case (https://developer.salesforce.com/docs/component-library/bundle/force:hasRecordId/documentation).
Once you get the Opportunity Id, you can use different methods to obtain the related Account's id. You can create an Apex Controller but you can also use the force:recordData component (https://developer.salesforce.com/docs/component-library/bundle/force:recordData/documentation) to obtain the Account Id.
<aura:component implements="force:lightningQuickActionWithoutHeader,force:hasRecordId">
<aura:attribute type="Opportunity" name="opportunity" />
<force:recordData
recordId="{!v.recordId}"
fields="AccountId"
targetFields="{!v.opportunity}"
/>
Are you sure you want to proceed?
<div class="slds-align_absolute-center">
<lightning:button
label="No"
variant="destructive"
onclick="{!handleNo}"
></lightning:button>
<lightning:button label="Yes" onclick="{!c.handleYes}"></lightning:button>
</div>
</aura:component>
Controller:
({
handleNo: function (component, event, helper) {
var accountId = component.get("v.opportunity.AccountId");
var urlEvent = $A.get("e.force:navigateToURL");
urlEvent.setParams({
url: "/apex/MyOtherVisualforce",
isredirect: "true"
});
urlEvent.fire();
},
handleYes: function (component, event, helper) {
var accountId = component.get("v.opportunity.AccountId");
var urlEvent = $A.get("e.force:navigateToURL");
urlEvent.setParams({
url: "/apex/MyVisualforce",
isredirect: "true"
});
urlEvent.fire();
}
});
How can I redirect inside an EventSubscriber, when creating a plugin?
I just subscribe to a specific event which inherits from PageLoadedEvent. In my method, I want just to redirect to another page.
For now, I can only redirect, overriding a controller, because only in the controller class, there are redirect-methods.
But I also just want to redirect, after a specific event was fired.
<?php declare(strict_types=1);
namespace My\Plugin\Storefront\Subscriber;
use Shopware\Storefront\Page\Account\Profile\AccountProfilePageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Psr\Container\ContainerInterface;
class Account implements EventSubscriberInterface {
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public static function getSubscribedEvents()
{
return [
AccountProfilePageLoadedEvent::class => 'onAccount'
];
}
public function onAccount(AccountProfilePageLoadedEvent $event) {
/**
* #var Symfony\Bundle\FrameworkBundle\Controller\RedirectController $redirectController
*/
$redirectController = $this->container->get('Symfony\Bundle\FrameworkBundle\Controller\RedirectController');
return $redirectController->redirectAction($event->getRequest(), "frontend.home.page");
}
}
I found the RedirectController, which I can inject to my Subscriber via services.xml.
The result returns a RedirectResponse. But returning that object won't happen anything. It should redirect to the homepage.
this is currently not possible if you subscribe to a PageLoadedEvent. I created a ticket for that in our internal issue tracker https://issues.shopware.com/issues/NEXT-5107
You could follow the state there.
In the meantime you could try to subscribe to \Symfony\Component\HttpKernel\KernelEvents::RESPONSE and do the redirect here.
Best regards from Schöppingen
Michael Telgmann
A little bit late, but it is possible with RedirectResponse:
\Symfony\Component\HttpFoundation\RedirectResponse
Example:
//if you want to redirect to controller which does not acepts xmlhttp request, you can use 201 response code as second argument
$response = new RedirectResponse($path);
$response->send();
You can generate the path using Shopware Router (you can attach it by DI to your subscriber):
\Shopware\Storefront\Framework\Routing\Router
Example:
$path = $this->router->generate('frontend.checkout.cart.page');
I'm trying to get the GitHub user picture (avatar) from users of GitHub.
I've found these API:
https://avatars.githubusercontent.com/<username>
https://avatars.githubusercontent.com/u/<userid>
But I can't find a way to get the avatar from the user email or the user display name.
I can't find documentation about that.
Is there some similar URL API to get what I'm looking for?
You can append .png to the URL for the User's profile to get redirected to their avatar. You can add the query param size to specify a size smaller than the default of 460px wide (i.e. it won't allow larger than 460).
Examples:
https://github.com/twbs.png
https://github.com/npm.png?size=200
https://github.com/github.png?size=40
https://developer.github.com/v3/users/#get-a-single-user
Use the /users/:user endpoint. Should be under avatar_url in the returned json.
For example, my avatar_url can be found by hitting this url.
Edit
There is another way I can think of that is kind of roundabout. Since GitHub uses Gravatar, if you know the email associated with the account, do an md5 hash of the lowercase, stripped email address and construct a url like http://www.gravatar.com/avatar/[md5_here].
This is an old post but nobody has proposed Github Search Users API with scope field :
using in:email : https://api.github.com/search/users?q=bmartel+in%3Aemail
using in:username : https://api.github.com/search/users?q=Bertrand+Martel+in%3Ausername
Or using new Graphql API v4 :
{
search(type: USER, query: "in:email bmartel", first: 1) {
userCount
edges {
node {
... on User {
avatarUrl
}
}
}
}
}
Using GraphQL API v4, this will work too
Query (for username)-
{
user(login: "username") {
avatarUrl
}
}
Response -
{
"data": {
"user": {
"avatarUrl": "https://avatars1.githubusercontent.com/u/..."
}
}
}
GitHub avatar can be accessed through https://avatars.githubusercontent.com/u/YOUR_USER_ID
Optionally, you can modify the size at the end like so https://avatars.githubusercontent.com/u/YOUR_USER_ID?s=460
I am getting this error
Call to undefined method SecurityComponent::allowedActions()
When I try to allow singup action in controller like this
public function beforeFilter() {
parent::beforeFilter();
$this->Security->allowedActions(array('sign-up'));
$this->Auth->allow('login','signup','index','activate','logout','forgot','reset','display');
if($this->Auth->user('id')) {
$this->set('logged_in', true);
} else {
$this->set('logged_in', false);
}
}
public $components = array('RequestHandler');
if i remove
$this->Security->allowedActions(array('sign-up'));
when I submit signup form, It shows your request has ben blackholed
There is no such method, allowedActions is a property of the SecurityComponent.
http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#SecurityComponent::$allowedActions
$this->Security->allowedActions = array('sign-up');
Also you are using signup in AuthComponent::allow(), so make sure sign-up is really the correct name of the action (which I really doubt as this would be invalid PHP syntax).