interaction design – ‘Add to Favorites’ state change immediately or wait for backend confirmation?

Optimistic updates can go wrong too, what if the network request takes time, and use closes the browser or leaves the site and thinks the interaction was successful because of the visual feedback he received?
In my opinion the best practice, for important interactions, is to use some transition that gives feedback on click, but does not hide the pending state in case it takes more than a second or two.
For low-importance interactions, like rating something or clicking ‘like’, the impact of errors is smaller, so optimistic updates are more ok.

reactjs – Using fetch post trying to senad usestate variable to backend, not working. React.js

Two buttons with its own function excuected when clicked, one is savedays and other is submitdays. I want to combine the functions so its only one button but i get this error.

const saveDays = async () => {
        await setSelectedDays(selectedDays => "");

        if(days.Monday == true){await setSelectedDays(selectedDays => selectedDays.concat("MON,"))};
        if(days.Tuesday == true){await setSelectedDays(selectedDays => selectedDays.concat("TUE,"))};
        if(days.Wednesday == true){await setSelectedDays(selectedDays => selectedDays.concat("WED,"))};
        if(days.Thursday == true){await setSelectedDays(selectedDays => selectedDays.concat("THUR,"))};
        if(days.Friday == true){await setSelectedDays(selectedDays => selectedDays.concat("FRI,"))};
        if(days.Saturday == true){await setSelectedDays(selectedDays => selectedDays.concat("SAT,"))};
        if(days.Sunday == true){await setSelectedDays(selectedDays => selectedDays.concat("SUN,"))};
        await setSelectedDays(selectedDays => selectedDays.slice(0, -1));
        console.log(selectedDays,"updated");
    }

const submitDays = async () => {
        let postRes = await fetch(`/addSurveyDays/${selectedDays}`, {
            // let postRes = await fetch(`/addSurveyTime/${e.target.checked}`, {
            method: "POST",
            headers : { 
                'Content-Type': 'application/json',
                'Accept': 'application/json'
            }
        });
        let postResult = await postRes.json();
        if (postResult.success) {
            // fetchSurveySystemInfo();
            console.log("succes posted")
        } else setEmailError("Something went wrong, please try again")
    }

But when i combine both this functions to be executed on click with a single button. I get this error the first time i run it.

Chrome console log, “POST HTTP://localhost:3000/addSurveyDays/ 404 (Not Found)

The error is only there the first time i run it, then its fine. can someone help explain why that is?

nodejs – ¿Cómo redireccionar desde el backend con express?

cómo puedo redireccionar a una ruta sin que me salga ese #_=_
introducir la descripción de la imagen aquí

Redirecciono usando el redirect

res.redirect(keys.frontend);

Donde keys.fronted tiene este valor

frontend: "http://localhost:3000",

En pocas palabras quiero que al redireccionar la ruta me la muestre limpia, algo así
introducir la descripción de la imagen aquí

o es algo que solo pasa en local y ya en producción sale completamente normal?
gracias.

azure – Mobile safari: angular http call to .netcore backend – 0 Unknown error

I have an angular application hosted in a web app in azure. It was created using the template in VS with a .Net Core back end. When the application is deployed it works fine on desktops, windows and macOS.

But on mobile safari I keep getting errors when trying to make an api call to fetch a token using azure b2c. The .net core code makes the call in order to get the token and return any other associated data from the database.

I’ve added application insights logging and get the following error:

{"headers":{"normalizedNames":{},"lazyUpdate":null,"headers":{}},"status":0,"statusText":"Unknown Error","url":"**********.azurewebsites.net/Auth/Token","ok":false,"name":"HttpErrorResponse","message":"Http failure response for ***********.azurewebsites.net/Auth/Token: 0 Unknown Error","error":{"isTrusted":true}}

This causes my application to go through a looping mechanism from my error page to try and authenticate. After searching endlessly on the web, I’ve ensured CORS is configured correctly and headers are set. But I’m really not sure where to go next.

.net core start up code:

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddApplicationInsightsTelemetry(Configuration("ApplicationInsights:InstrumentationKey") ?? string.Empty);

            ConfigureIoC(services);

            MapperConfiguration mappingConfig = new MapperConfiguration(mc =>
            {
                mc.AddProfile(new AutoMapperConfig());
            });
            services.AddSingleton(mappingConfig.CreateMapper());

            services.AddCors();

            services.AddControllersWithViews(options =>
            {
                options.RespectBrowserAcceptHeader = true;
            }).AddNewtonsoftJson();

            //Azure AD - B2C
            ConfigureAuth(services);
            
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/dist";
            });
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                IdentityModelEventSource.ShowPII = true;
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            if (!env.IsDevelopment())
            {
                app.UseSpaStaticFiles();
            }

            app.UseRouting();
            app.UseCors(builder => {
                builder.AllowAnyOrigin();
                builder.AllowAnyMethod();
                builder.AllowAnyHeader();
            });
            app.UseAuthentication();
            app.UseAuthorization();
            
            app.UseMiddleware<ErrorHandlingMiddleware>();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller}/{action=Index}/{id?}");
            });

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                    spa.Options.StartupTimeout = TimeSpan.FromSeconds(200);
                }
            });
        }
    }

Angular http intercepter code:

 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any> | any> {
    return next.handle(this.addTokenToRequest(request, this.authService.tokenSubject.value)).pipe(
      tap(res => {
        if (res instanceof HttpResponse) {
          this.decreaseRequests();
        }
      }),
      catchError(err => {
        this.decreaseRequests();
      
        if (err instanceof HttpErrorResponse) {
          switch ((<HttpErrorResponse>err).status) {
            case 401:
              this.authService.logOut();
              return;
              //return this.handle401Error(request, next);
            case 200:
              return;
            default:
              return this.handleError(err);
          }
        } else {
          this.logger.logTrace(`Interceptor: Error - ${err}`);
          return throwError(err);
        }
      })
    );
  };

  private decreaseRequests() {
    this.totalRequests--;
  }

  private addTokenToRequest(request: HttpRequest<any>, token: string): HttpRequest<any> {
    return request.clone({
      headers: new HttpHeaders({
        'Content-Type': 'application/json',
        Accept: 'application/json',
        Authorization: 'Bearer ' + token
      })
    });
  }

When running fiddler, this is my request:
fiddler-image

Top 5 Backend Development Frameworks

 

Como integrar um backend feito em python com um frontend feito em React-Native para app

Obrigado por contribuir com o Stack Overflow em Português!

  • Certifique-se de responder à pergunta. Entre em detalhes sobre a sua solução e compartilhe o que você descobriu.

Mas evite

  • Pedir esclarecimentos ou detalhes sobre outras respostas.
  • Fazer afirmações baseadas apenas na sua opinião; aponte referências ou experiências anteriores.

Para aprender mais, veja nossas dicas sobre como escrever boas respostas.

Magento2: custom payment module, show options in backend

I have created a custom payment module called “Pagamentodilazionato”. When a customer chooses this method, a select appears next to it from which to choose some options.

app/code/Infocurci/Pagamentodilazionato/view/frontend/web/js/view/payment/method-renderer/pagamentodilazionato.js

define(
    (
        'Magento_Checkout/js/view/payment/default',
         'jquery'
    ),
    function (Component,$) {
        'use strict';

        return Component.extend({
            defaults: {
                template: 'Infocurci_Pagamentodilazionato/payment/pagamentodilazionato'
            },
            
            getStoreCard: function() {
                return  window.checkoutConfig.payment.pagamentodilazionato.storedCards;
            },
            
            getData: function() {
                var data = {
                    'method': this.item.method,
                    'additional_data': {
                        'method_title': 'tessss',
                        'condizionipagamento': $('#' +this.getCode() +'_condizionipagamento').val()
                    }
                };
                return data;
            },
            
            getCardList: function() {
                return _.map(this.getStoreCard(), function(value, key) {
                    return {
                        'value': key,
                        'type': value
                    }
                });
            },
    
        });
    }
);

app/code/Infocurci/Pagamentodilazionato/Model/MetodiConfigProvider.php

<?php
   namespace InfocurciPagamentodilazionatoModel;

   use MagentoCheckoutModelConfigProviderInterface;
   use MagentoCustomerModelSession as CustomerSession;
   use MagentoFrameworkAppResourceConnection;
   use MagentoFrameworkAppState;

   /**
     * Class MetodiConfigProvider
    */
   class MetodiConfigProvider implements ConfigProviderInterface
   {
       
    protected $_customerSession;
    protected $_resourceConnection;
    protected $_state;
    
    public function __construct(
        CustomerSession $customerSession,
        ResourceConnection $resourceConnection,
        State $state 
    ){
        $this->_customerSession = $customerSession;
        $this->_resourceConnection = $resourceConnection;
        $this->_state = $state;
    }
    
    public function getStoredCards(){
        $result = array();
        if($this->_customerSession ||  $this->_state->getAreaCode() == MagentoFrameworkAppArea::AREA_ADMINHTML)
        {
            if($this->_state->getAreaCode() == MagentoFrameworkAppArea::AREA_ADMINHTML)
            {
                $customerId = $observer->getEvent()->getQuote()->getCustomerId(); //attenzione che in backend questo observer viene chiamato anche prima che venga scelto il cliente, per cui dopo è essenziale if($customerId)
            }
            else
            {
                $customerId = $this->_customerSession->getId();
            }
            if($customerId)
            {
                $connection = $this->_resourceConnection->getConnection();
                $resultPreimpostati = $connection->fetchAll('select pagamentodilazionato_metodo from bioalgheprof_pagamentodilazionato where customer_id='.$this->_customerSession->getId());
                if(!empty($resultPreimpostati))
                {
                    foreach($resultPreimpostati as $preimpostato)
                    {
                        $result($preimpostato('pagamentodilazionato_metodo')) = str_replace('_',' ',$preimpostato('pagamentodilazionato_metodo'));
                    }
                }
            }
        }
        
      return $result;
    }

    public function getConfig()
    {
    $config = ();
    $config = array_merge_recursive($config, (
        'payment' => (
            InfocurciPagamentodilazionatoModelPaymentMethod::CODE => (
                'storedCards' => $this->getStoredCards(),
            ),
        ),
    ));
    return $config;
   }
}

works well. However, if I log in as an administrator and try to create an order for a customer, the payment method appears without the select to choose the options.

How can I solve? Should I copy the dilated payment.js file to / view / adminhtml as well?

front end – Shared data structures between frontend and backend

Over the last years I noticed, that when it comes to architecture of web applications, the frontend is not getting nearly as much consideration as the backend. In general, I understand why the backend gets more attention when it comes to the software architecture and data modelling. However, since I am a full-stack developer, it always bothered me that I didn’t get in touch with good concepts for managing the data model in both backend and frontend.

Some of the technologies and concepts we use and work with:

  • frontend: React/TypeScript
  • backend: Java/Kotlin
  • REST

The problem:

In one of my current projects, we have concepts for modelling data in backends. But as far as I am aware of, there are no established rules or best practices how the frontend should deal with it.

Current situation in one of my projects.

In the backend we have layers and models that help us to make a ‘cleaner’ software. We have a layer that retrieves and persists the data and therefore a model for this type of data (entities), we have value objects and we have a model for transferring and receiving the data to the frontend (data transfer objects (DTOs)).

For now, what our React frontend does is just using TypeScripts type to replicate the model defined by the backend, which is represented as a DTO.

I don’t think that this approach is good enough since it has several flaws:

  • Having the type definition maintained in the frontend seems unnecessary, since the model of the object is already defined in the backend.
  • Changing the model of the DTO always requires a change of the type definition.
  • While there are rules for many attributes in the backend, the frontend doesn’t know these rules and only ‘knows’ it when the backend complains (e.g. a birthday date shall not be a date in the future).
  • The frontend replicates these rules and maybe even adds more rules for input validation (e.g. the frontend doesn’t allow the date of the birthday to be 200 years in the past).

In short, the rules/constraints and models are relevant for both frontend and backend, but the frontend isn’t informed about the models and constraints on attributes.

Possible solution:

  • Requesting the model from the backend: It is possible to generate the model as type definitions, but this would be to difficult in my opinion, since it requires a overcomplicated build process where the backend (after being build) sends the models to the frontend that rely on it for successfully building the frontend app.
  • Requesting the attribute constraints from the backend: This would be easier to establish, since it doesn’t require the frontend to wait for the backend.
  • Validation of the frontend model defined by TypeScripts type: We could have a solution where we have a replication of the DTO models in the frontend, where at the application start of the frontend, the frontend requests a confirmation of the backend. This requires an API function that matches the backend defined DTO models with the frontend defined type definitions.

The question:

I am not so happy with the overhead of these solutions. Is there an easier/better way of dealing with the problem of shared data models?