Tu as dis "chez les anglo-saxons" où Laravel est très loin devant Symfony.
Je veux installer une version de développement Wordpress pour la refonte d'un site et je me demandais si c'était une bonne idée de faire ça sur un nouveau serveur tout propre, différent de celui qui héberge actuellement celui en production, sachant que je vais travailler avec git.
Ouais tu as raison, mais non en fait parce que ça me lourde de configurer l'environnement sous linux, j'y ai déjà passé des heures et ça ne se comporte jamais comme en prod.
Au moins là, je n'aurai pas de surprise avec cet aspect. Et je m'aperçois que je réponds à mes propres questions...
Je précise donc mes interrogations, j'ai près de 50000 images à transférer et je voulais savoir, en fait, si je pouvais le faire en SSH d'un serveur à l'autre. La réponse est peut-être évidente mais c'est pas ma spécialité et ça me rassure de vous demander avant.
Supayr jaynial je vais regarder ça, merci !
EDIT : je viens de regarder la documentation, c'est exactement ce qu'il me fallait, merci encore.
Dernière modification par mellifico ; 29/09/2019 à 22h41.
Ah tiens on m'a parlé de Laravel au boulot justement, on va récupérer un projet là dessous et personne au taf n'est formé.
Ca vaut le coup que j'essaie de choper une formation ? C'est pas mal pour se vendre par rapport à du Symfony ?
Bon pour l'instant je monte en puissance en java mais je bosserai sur plusieurs projets (java ou php donc), il y a un projet en php qui passe par Laravel.
Je ne serai pas le seul candidat donc on verra bien. Il y aura au moins 2 élus ...
Y'a des gens qui vont au DevFest Toulouse cette semaine ?
Hello les coincoins,
Je bosse un peu plus sur angular7 à présent.
Cependant, j'ai quelques questions concernant les observables qui remplacent les anciennes promises avec les input d'auto-complétion.
J'ai un cas d'auto-complétion qui passe bien, en sachant que c'est mon micro service qui est en charge du filtrage.
Le cas qui me pose problème, c'est pour le cas de mes pays, où le micro service ne filtre pas.
J'ai tenté en faisant du filtrage au niveau du service angular.
Pour l'autocomplétion de l'input je passe par ngx-bootstrap.
Dans l'HTML j'ai donc un
J'ai un service pour gérer l'appel à mon micro serviceCode:<input .... [typeahead]="listePays" formControlName="paysInput" ..../>
Je ne mets pas la déclaration des interface pour le model
Dans mon Component :Code:// snip les imports etc... export class MonService { constructor(private http: HttpClient) { } // Recupère les pays { listPays: [{code: string, nom: string}] } // Je remets mon code que j'ai encore en tête mais pas sur de l'exactitude getPays(filtre: string): Observable<Pays[]> { return this.http.get<ListPays>('/api/monservice/v1/pays').map(res => res.listPays).filter(p: Pays => { const regex = new RegExp(filtre, 'i'); return regex.test(p.nom); }); } }
J'aimerai bien des articles pour mon comprendre les observables et toutes ces notions de map, filtre etc..., je ne suis pas encore totalement à l'aise avec les lambda.Code://snip déclarations habituelles (imports, etc) export class MonComponent { // Ma liste de pays pour le binding sur le typeahead listePays: Observable<any>; constructor(private monService: MonService) {} ngOnInit(): void { listePays = new Observable((observer: any) => { observer.next(this.paysInput.value); }).pipe(mergeMap((filtre: string) => this.monService.getPays(filtre)); } // Déclaration d'un getter pour accéder à la propriété du reactive form }
Merci pour votre aide.
Pour la doc, celle officielle est plutôt bien foutue et explique chaque opérateur avec un "marble diagram" (diagramme à billes) qui permet de représenter facilement le côté dynamique des observables.
Un de ses éléments bien pratique est l'arbre de décision qui permet de trouver le bon opérateur pour un besoin précis.
Pour répondre à ta question, on est bien d'accord que c'est ce composant que tu utilises : https://ng-bootstrap.github.io/#/components/typeahead ? (je pose la question car l'attribut décris dans la doc est nomma "ngbTypeahead" et non "typeahead" comme dans ton exemple).
Et dans le cas de ton API pour les pays, elle renvoie simplement une liste statique qui ne change pas à chaque appel ?
C'est la faute à Arteis
Les observables ne remplacent pas les promises : c'est des usages différents. Vois la promise comme un observable qui ne s’exécutera qu'une fois (résultat ou exception).
De plus, si tu veux absolument modéliser des streams, tu peux aussi directement utiliser des objets comme Subject/BehaviorSubject/etc.
Pour la doc, regarde la documentation de Rx et tout ce qui touche la programmation réactive : http://reactivex.io/documentation/observable.html
Comme tu fait des appels HTTP (et pas du Websocket), je serai plutôt incliné à créer ton service avec une Promise (plus proche au niveau du comportement) et de faire ta chaîne d'auto-completion de l’autre coté.
Merci pour vos réponses.
Pour la documentation, j'avais vu quelques diagrammes à billes, mais ce n'était pas sur le site officiel et il ne listait pas l'ensemble des opérateurs. Je mets ça de côté.
Cool pour l'arbre de décision, ça devrait m'éviter d'utiliser juste les opérateurs que je maitrise mais qui ne sont pas forcement adaptés.
Pour le composant que j'utilise, c'est celui-ci (https://valor-software.com/ngx-bootstrap/#/typeahead)
La promise est peut-être plus adaptée dans le cas de mon service des pays en sachant que le json retourné par le service n'évolue pas au cours de la journée.
Tu peux en effet dans ce cas cacher la valeur dans ton service et la retourner directement par Promise.resolve() tant qu'elle est "fraîche".
Je ne vois pas vraiment l'intérêt de passer par une Promise, le client Http d'Angular retourne des Observable, autant les utiliser directement.
Par contre ton cas est bien plus simple que ce que tu présentais vu que tes données sont statiques.
Tu peux simplement faire :
Template du component (HTML) :
Service :Code:<input ... [typeahead]="listPays" // On passe directement le tableau statique des pays typeaheadOptionField="nom" // Permet de dire sur quel membre des objets représentants les pays on fait l'autocomplete formControlName="paysInput" ... />
Component :Code:// snip les imports etc... export class MonService { constructor(private http: HttpClient) { } getListPays(): Observable<Pays[]> { return this.http.get<ListPays>('/api/monservice/v1/pays').pipe( map(res => res.listPays) // Le map ici permet de ne retourner que ce qui nous intéresse dans le retour WS ); } }
Code://snip déclarations habituelles (imports, etc) export class MonComponent { listPays: any[]; // Liste statique des pays qu'on va passer à l'input constructor(private monService: MonService) {} ngOnInit(): void { this.monService.getListPays().subscribe(listPays => this.listPays = listPays); // On fait juste l'appel au service pour initialiser la liste des Pays } }
C'est la faute à Arteis
Merci beaucoup pour vos conseils, j'ai rebossé sur le sujet aujourd'hui avec la doc rxjs sous la main (qui m'a bien aidée).
Il me semble que j'avais tenté ce que tu as décris Orhin, mais que je n'obtenais pas le résultat attendu. Je retenterai.
Pour le service j'ai pondu ça qui fonctionne (mais c'est vrai que ça semble un peu overkill à mon goût pour un truc super simple) :
Je tente aussi d'appliquer tes conseils sur l'architecture d'un projet Angular 2+ (ce qu'importe et exporte le sharedModule, le coreModule, etc).Code:// snip les imports etc... export class MonService { constructor(private http: HttpClient) { } cachedPays: Observable<Pays[]>; getPays(filtre: string): Observable<Pays[]> { // On cache l'appel if (!this.cachedPays) { this.cachedPays = this.requestListPays().pipe(shareReplay(1)); } // On filtre ce qui nous intéresse const query = new RegExp(filtre, 'i'); return this.cachedPays.pipe(filter((pays: Pays) => query.test(pays.nom))); } private requestListPays(): Observable<Pays[]> { return this.http.get<ListPays>('/api/monservice/v1/pays').pipe( map(res => res.listPays) // Le map ici permet de ne retourner que ce qui nous intéresse dans le retour WS ); } }
J'aimerai bien ton avis aussi sur la façon dont j'ai géré un reactive form.
J'ai créé un formulaire avec un premier choix qui conditionne l'affichage de champs à saisir (qui sont obligatoires).
Je ne pouvais pas mettre le Validators.required au niveau de la construction du formulaire sans quoi les champs non affichés (par un ngIf ou ngSwich) étaient tout de même requis.
J'ai fait quelque chose comme ça :
Ça fait ce qui est attendu, mais je trouve ça un peu lourd. Je me dis que dans mon cas réel avec 3 champs et 2 sous champs max par choix, ça reste raisonnable, mais dans un formulaire plus complexe, ça pourrait rapidement devenir complexe.Code:this.monFormulaire.controls['choix'].valueChanges.subscribe(value => { this.monFormulaire.controls['input1'].setValidators(null); this.monFormulaire.controls['input2'].setValidators(null); if (value === 'choix1') { this.monFormulaire.controls['input1'].setValidators(Validators.required); } else { this.monFormulaire.controls['input2'].setValidators(Validators.required); } this.monFormulaire.controls["input1"].updateValueAndValidity(); this.monFormulaire.controls["input2"].updateValueAndValidity(); });
C'était une réflexion de haut niveau : comme un appel HTTP est plus proche d'une promise que d'un observable au niveau du comportement, il est plus logique de retourner une promise au niveau de la modélisation. Ça rends tout le reste plus logique d'un point de vu domain model ("souscrire à un appel REST" ça n'a aucuns sens : il va pas se mettre à se comporter comme un stream, par contre dire "après l'appel REST je fais ci, et je fais ça, et si j'attrape une erreur je fais encore ça" là ça a beaucoup plus de sens).
Après visiblement son component utilise un observable, donc oui, c'est sans doutes pas utile dans ce cas précis, je réagissais juste à la phrase "l’observable qui remplace la promise".
Ps: avec une promise ça donne ça :
Ce qui (sans même avoir besoin d'aller lire le service) te donne une bien meilleure compréhension du comportement sous-jacent.Code:ngOnInit(): void { this.monService.getListPays() .then(listPays => this.listPays = listPays) .catch(err => handleError(err)); }
1) Le client HTTP d'Angular retourne des Observable, donc si tu veux retourner une promise après un appel WS tu dois faire une opération supplémentaire (avec l'opérateur "toPromise" par exemple) ce qui est donc moins économe (même si marginal d'un point de vue perf)
2) Ton component n'est pas censé savoir que ton service fait un appel WS pour récupérer les données, il veut juste de la donnée et le service doit se démerder pour lui fournir. Si tu vas au delà tu couples déjà trop ton service et ton component
3) Tu peux très bien avoir un appel WS retournant un flux de donnée. 2 cas concrets :
a) Ton WS met beaucoup de temps à répondre => tu retournes la dernière valeur en cache puis la valeur du retour WS
b) Ton WS est paginé mais tu as envie de récupérer plusieurs pages => ton service va faire plusieurs appels à la suite et retourner la liste mise à jour à chaque retour WS
Ouais enfin avec un Observable ça donne ça :
Niveau lisibilité et compréhension je ne vois aucune différence.Code:ngOnInit(): void { this.monService.getListPays() .subscribe( listPays => this.listPays = listPays, handleError ) }
C'est la faute à Arteis
Justement, si t'a un WS il vaux mieux le définir clairement pour en exploiter toute la puissance : donc tu le mettra derrière un BehaviorSubject par exemple.
Si t'a une technologie de type Stream, tu le met derrière un objet modélisant un stream.
Si t'a une technologie d'appel asynchrone, tu le met derrière un object modélisant un appel asynchrone.
Un appel HTTP n'est pas un stream de données, si tu code de l'autre coté en sachant que malgré l'interface (un observable, donc un stream), c'est un appel asynchrone, tu n'isole rien, et en fait tout est lié.
Par exemple, le jour où je veux lancer deux appels API en parallèle et en lancer un second après l'un des deux, puis attendre la fin des trois, si j'ai des objets de type Promise je sais (sans même regarder le service) ce que je manipule et peux les combiner facilement (en chaînant les promesses, en les attendant avec Promise.all() etc). Avec des observables, c'est moyen pour faire ce genre de choses, et le jour ou tu change l'appel HTTP par une implémentation WS, tu va tout péter derrière.
ps: osef de l'implémentation d'angular, là ces concepts dépassent Angular ou le Javascript : c'est valide partout. Par exemple en C# .NET on a aussi les Task (Promise) et Observable (Observable), et je ferai la même réflexion si quelqu'un utilisait l'un à la place de l'autre.
Y'a des gens qui utilisent Docker ici ? J'ai un peu de mal à comprendre certains trucs.
J'utilise Homestead (Vagrant) depuis longtemps sur mon mac, pour des projets de tous types (Symfony, Laravel mais aussi Wordpress). Ça fonctionne bien mais c'est ultra lourd je trouve. Ça bouffe une mémoire et du CPU à foison, sans compter ma batterie. Basculer sur Docker me plaît bien, j'entends partout que c'est beaucoup plus léger à utiliser que Vagrant. Et j'aime bien l'idée de faire du déploiement avec.
Je crois comprendre le concept des containers : je peux installer la stack nécessaire (la version de PHP que je veux, MySQL, etc..), et je peux faire un docker par projet de manière à avoir un contrôle total sur mes projets. Une fois le container prêt, si je comprends bien on le build, donc ça embarque toute la stack logicielle et le code source, et on peut déposer ça sur un serveur ou même la partager avec les collègues pour qu'ils aient le même environnement de travail. Le code source continue sa vie sur GitHub, et la "machine" se trouve sur le Hub de Docker.
Cependant hier j'ai par exemple eu à installer un binaire sur Homestead (en l'occurence wkhtmltopdf, pour générer des PDF à partir de templates Twig). Je me suis donc loggé en SSH dans ma VM (Homestead est basé sur Ubuntu) et j'ai procédé à l'installation de mon logiciel. Mais comment je peux faire ça sur un Docker ? Si je comprends bien, je n'ai que PHP/MySQL/etc.. mais ça repose sur mon OS (en l'occurence MacOS). Donc si je veux un binaire bien précis, je dois l'installer sur mon OS hôte ?
Also, j'ai des projets qui ont besoin de versions de PHP différentes. Homestead gère bien ça, mais comment ça se passe avec Docker si j'ai des librairies PHP à installer pour un projet et pas l'autre ? (ça rejoint ma question précédente). Et comment faire pour entrer des commandes PHP au projet ? (typiquement les php artisan ou php bin/console)
Merci pour votre aide les coins !
Un container est composé de couches. Tu peux par exemple partir de la couche Ubuntu (pour avoir un equivalent Homestead) et y ajouter tes couches (par ex ta bdd, ton serveur, ta stack + ton code).
Ensuite tu build et tu partage l'image.
Une fois l'image lancée il est possible d'aller y ouvrir un shell et s'amuser dedans.
Oula, toi tu veux faire de l'anti pattern total avec Docker. Bon je reprends, tu fais des images Docker (avec ton dockerfile) qui utilisent d'autres images publique et/ou perso, c'est ça les couches.
Ensuite pour tes applis spécifiques tu utilises le dockerfile avec lequel tu peux transférer et faire qu'elles s'installent dans ton conteneur au moment du lancement de celui-ci.
Ensuite, le conteneur n'est pas fait pour échanger du code, t'es même pas censé avoir du code dedans (bon pour le PHP, je sais pas).
Par contre tu peux avoir plusieurs images différentes avec plusieurs versions de PHP par exemple, et t'en servir comme image de base.
Il faut juste retenir une chose, un conteneur n'est pas une VM, tu ne bosses pas directement dedans, en fait, la bonne pratique, c'est de penser les conteneurs comme immutables, ça simplifie grandement les choses. Là je suis sur mon tél, si tu veux en parler on peut faire ça par mp
Hey les canards! Je cherche une solution pour avoir rapidement un dev Prestashop pour des dépannes ponctuelles quand je veux régler un problème en urgence ou quand je veux faire un truc sans avoir le temps d'y passer des plombes.
Est-ce que y a des entreprises pour ça ? Y a un site de confiance ? Un canard fait du freelance dans le domaine ?
Merci pour vos lumières, c'est une question que j'aurais dû poser il y a longtemps.
EDIT : tompalmer m'a recommandé Fiverr par MP. Comme c'est la seule suggestion, je vais partir là-dessus
Dernière modification par MrBeaner ; 30/10/2019 à 11h39.
Je pense que l'idéal c'est de trouver un freelance qui soit un peu de confiance et que tu puisses solliciter quand tu as besoin.
Essaye de regarder les free dispo sur Malt.
Protip, essaye plutôt les plus chers que l'inverse, beaucoup de gens avec peu d'expérience ont tendance à tirer les prix par le bas
(typiquement le moins cher que je vois là en un coup d'oeuil est à 190/jour, c'est vraiment trop peu)